在服务器 PowerShell 列表中查找用户

find User in a list of servers PowerShell

我有一个服务器列表,我必须在其中找到特定用户 'adtuser',如果它是每个服务器中管理员组的一部分,则输出一个文本文件。

目前我有这个脚本并且它部分有效。
我有想要的输出,但是缺少一些服务器(如果你单独检查它们就可以)并且脚本需要很多时间。

提前致谢

Get-Content C:\servers.txt | ForEach-Object {
    if (-not (Test-Connection -ComputerName $_ -Count 1 -Quiet)) {
        Write-Warning "Server '$_' is Unreachable hence Could not fetch data"
        return
    }
    
    $computer = $_
    ([adsi]"WinNT://$_").Children.ForEach{ 
        if($_.SchemaClassName -ne 'user' -and $_.Name.Value -ne 'ADTuser') {
            return
        }
        
        $groups = $_.Groups().ForEach([adsi]).Name
        
        [pscustomobject]@{
            Computername = $computer
            UserName     = $_.Name.Value
            Memberof     = $groups -join ';'
            Status       = $groups -contains 'Administrators'
        }
    }
} | Out-File -FilePath C:\users.txt

请注意,test-netconnection 需要 powerhshell 2.0 或更高版本。方法 .ForEach 需要 Powershell 4.0 或更高版本。

正如 @Santiago 提到的——我使用 Test-Connection-port 3389 来测试 Windows RDP 端口。 OP 最初只是测试 ICMP 连接,由于常见的防火墙规则,这是一个糟糕的测试。

您可以测试任何已知的 Windows 端口,但假设 RDP 已打开通常是非常安全的。 NMAP(或者你的网络管理员…grin)可能会给你最好的指导。

#!/usr/bin/env powershell
Get-Content -Path $env:HOMEDRIVE/servers.txt | ForEach-Object {
if (-not (Test-Connection -ComputerName $_ -Count 1 -Quiet)) {
    Write-Warning -Message ("Server '{0}' is Unreachable hence Could not fetch data" -f $_)
    return
}

$computer = $_
([adsi]('WinNT://{0}' -f $_)).Children.ForEach{ 
    if($_.SchemaClassName -ne 'user' -and $_.Name.Value -ne 'ADTuser') {
        return
    }
    
$groups = $_.Groups().ForEach([adsi]).Name
    
[pscustomobject]@{
        Computername = $computer
        UserName     = $_.Name.Value
        Memberof     = $groups -join ';'
        Status       = $groups -contains 'Administrators'
  }
 }
} | Out-File -FilePath $env:HOMEDRIVE/users.txt

既然你问了,如果你的服务器都可以使用 PowerShell 5.1 或更高版本,你可以使用 Get-Local* cmdlet。

从你的问题来看,你是专门找某个用户的ADTuser

$userToCheck = 'ADTuser'
$servers     = Get-Content -Path 'C:\servers.txt'
$cred        = Get-Credential -Message 'Please enter your admin credentials'

# loop through the list of servers and collect the output objects
$result = foreach ($computer in $servers) {
    if (-not (Test-Connection -ComputerName $computer -Count 1 -Quiet)) {
        Write-Warning -Message "Server '$computer' is Unreachable hence Could not fetch data"
        # output a failed object
        '' | Select-Object @{Name = 'ComputerName'; Expression = {$computer}}, UserName,MemberOf, 
                           @{Name = 'Status'; Expression = {'Unreachable'}}
        # skip processing this server and proceed with the next one
        continue
    }
    # here we probe the server for the existance of user $userToCheck
    $out = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
        $user = Get-LocalUser -Name $using:userToCheck -ErrorAction SilentlyContinue
        if ($user) {
            # get the names of all local groups the user is member of
            $userGroups = (Get-LocalGroup | Where-Object { ($_ | Get-LocalGroupMember).SID -contains $user.SID }).Name
            [PsCustomObject]@{
                Computername = $env:COMPUTERNAME
                UserName     = $user.Name
                MemberOf     = $userGroups -join '; '
                Status       = $userGroups -contains 'Administrators'
            }
        }
        else {
            [PsCustomObject]@{
                Computername = $env:COMPUTERNAME
                UserName     = $using:userToCheck
                MemberOf     = $null
                Status       = "User does not exist"
            }                
        }
    }
    # output the object but remove extra properties PowerShell added
    $out | Select-Object * -ExcludeProperty PS*, RunspaceId
}

# show in the console window
$result | Format-Table -AutoSize

# you can now use Export-Csv to output the results in a structured file you can open with Excel
$result | Export-Csv -Path 'C:\users.csv' -UseCulture -NoTypeInformation