在服务器 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
我有一个服务器列表,我必须在其中找到特定用户 '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