[英]Listing local administrator group membership on all domain computers
完整的powershell和腳本noob在這里 - 我甚至不知道危險。 我需要查詢域中的所有PC以確定其本地Administrators組成員身份是什么,並將該輸出發送到text / csv文件。
我嘗試了很多東西,比如:
Import-Module -Name ActiveDirectory
Get-ADComputer -filter * |
Foreach-Object {
invoke-command {net localgroup administrators} -EA silentlyContinue |
} |
Out-File c:\users\ftcadmin\test.txt
這讓我重復了一個相同的列表但似乎正在擊中每個域PC。 我猜它實際上並沒有在遠程PC上運行。 還嘗試過:
$computers = Get-Content -Path c:\users\ftcadmin\computers.txt
invoke-command {net localgroup administrators} -cn $computers -EA silentlyContinue
Get-Process | Out-File c:\users\ftcadmin\test.txt
這受到computers.txt文件中預定PC列表的限制。 我試過的第三件事就是:
$a = Get-Content "C:\users\ftcadmin\computers.txt"
Start-Transcript -path C:\users\ftcadmin\output.txt -append
foreach ($i in $a)
{ $i + "`n" + "===="; net localgroup "Administrators"}
Stop-Transcript
除了輸出之外,它似乎最具潛力
computername1
====
computername2
====
等沒有任何小組成員列表。
來自社區的任何想法?
將此功能復制並粘貼到PowerShell控制台中。
function Get-LocalGroupMember
{
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Name,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$ComputerName = 'localhost',
[Parameter()]
[ValidateNotNullOrEmpty()]
[pscredential]$Credential
)
process
{
try
{
$params = @{
'ComputerName' = $ComputerName
}
if ($PSBoundParameters.ContainsKey('Credential'))
{
$params.Credential = $Credential
}
$sb = {
$group = [ADSI]"WinNT://./$using:Name"
@($group.Invoke("Members")) | foreach {
$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}
}
Invoke-Command @params -ScriptBlock $sb
}
catch
{
Write-Error $_.Exception.Message
}
}
}
然后,嘗試使用它:
Get-ADComputer -filter * | foreach {Get-LocalGroupMember -Name 'Administrators' -ComputerName $_.Name }
如果你想做一些格式化,你可以得到一個計算機列表,並在每個計算機旁邊都有所有成員。
Get-ADComputer -filter * | foreach {
$members = Get-LocalGroupMember -Name 'Administrators' -ComputerName $_.Name
[pscustomobject]@{
'ComputerName' = $_.Name
'Members' = $members
}
}
這至少需要PowerShell v3。 如果您沒有,我強烈建議您升級到PowerShell v4。
在PowerShell版本5.1(WMF 5.1或Windows 10版本1607附帶的版本)中,現在(最終)有用於管理本地用戶和組的cmdlet。 https://technet.microsoft.com/en-us/library/mt651681.aspx
例如,要獲取本地Administrators組的成員,您可以使用
Get-LocalGroupMember -Group "Administrators"
遺憾的是,這些新cmdlet沒有用於遠程運行命令的ComputerName參數。 您需要使用Invoke-Command之類的東西遠程運行命令,遠程計算機也需要使用PowerShell版本5.1。
Invoke-Command cmdlet的ComputerName參數不接受管道輸入,它只接受字符串,因此我們首先需要展開Get-ADComputer返回的name屬性並將字符串存儲在變量中。 值得慶幸的是,該參數接受多個字符串,因此我們可以在單個invoke-command調用中使用$ names變量。 示例如下:
$names = Get-ADComputer -Filter * | Select-Object -ExpandProperty name
Invoke-Command -ScriptBlock {Get-LocalGroupMember -Group "Administrators"} -ComputerName $names
這實際上是我最近的工作。 似乎有兩種常規方法可以從本地Administrators組獲取成員:WMI和ADSI。
在我看來,更好的方法是使用WMI查詢來獲取成員,因為這包括域,因此您知道列出的用戶/組是服務器本地還是域帳戶。
使用ADSI的簡單方法不包括此信息,但不太可能獲得拒絕訪問類型的錯誤。
為此,我拼湊了一個腳本,檢查過去30天內活動的機器的AD(如果它不在線,則不需要浪費時間)。 然后,對於每個人,它嘗試執行WMI查詢以獲取管理員成員,如果失敗則轉向ADSI查詢。 數據存儲為哈希表,因為在我看來,這是管理嵌套數組的簡單方法。
$TMinus30 = [datetime]::Now.AddDays(-30).ToFileTime()
$Domains = 'ChinchillaFarm.COM','TacoTruck.Net'
$ServerHT = @{}
$Servers = ForEach($Domain in $Domains){Get-ADObject -LDAPFilter "(&(objectCategory=computer)(name=*))" -Server $Domain | ?{$_.lastLogonTimestamp -gt $TMinus30}}
$Servers.DNSHostName | %{$ServerHT.Add($_,$Null)}
ForEach($Server in ($Servers | ?{$(Test-Connection $_.DNSHostName -Count 1 -Quiet)})){
Try{
$GMembers = Get-WmiObject -ComputerName $Server -Query "SELECT * FROM win32_GroupUser WHERE GroupComponent = ""Win32_Group.Domain='$Server',Name='Administrators'"""
$Members = $GMembers | ?{$_.PartComponent -match 'Domain="(.+?)",Name="(.+?)"'}|%{[PSCustomObject]@{'Domain'=$Matches[1];'Account'=$Matches[2]}}
}
Catch{
$group = [ADSI]("WinNT://$Server/Administrators,group")
$GMembers = $group.psbase.invoke("Members")
$Members = $GMembers | ForEach-Object {[PSCustomObject]@{'Domain'='';'Account'=$_.GetType().InvokeMember("Name",'GetProperty', $null, $_, $null)}}
}
$ServerHT.$Server = $Members
}
然后,您只需要輸出到文件。 這就是我要做的,應該輸出你想要的東西:
$ServerHT.keys|%{"`n"+("="*$_.length);$_;("="*$_.length)+"`n";$ServerHT.$_|%{"{0}{1}" -f $(If($_.Domain){$_.Domain+"\"}), $_.Account}}
如果前兩個服務器響應WMI查詢而第三個服務器沒有響應,則會給出類似下面的內容:
===========
ServerSQL01
===========
ServerSQL01\SQLAdmin
TacoTruck\TMTech
TacoTruck\Stan2112
======
XWeb03
======
ChinchillaFarm\Stan2112
============
BrokenOld486
============
TMTech
Guest
如果有人將Guest帳戶放在本地管理員組中,那么最后一個會在我的書中觸發一些危險信號,但我想這可能是你首先這樣做的原因之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.