在这里完成PowerShell和脚本编写器 - 我甚至不知道是不是很危险。我需要查询域中的所有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
====
等没有任何小组成员列表。
来自社区的任何想法?
答案 0 :(得分:2)
将此功能复制并粘贴到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。
答案 1 :(得分:1)
在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
答案 2 :(得分:0)
这实际上是我最近做过的事情。似乎有两种常规方法可以从本地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帐户放在本地管理员组中,那最后一个会在我的书中触发一些危险信号,但我想这可能是你首先这样做的原因之一。