简体   繁体   English

在所有域计算机上列出本地管理员组成员身份

[英]Listing local administrator group membership on all domain computers

Complete powershell and scripting noob here - I don't even know enough to be dangerous. 完整的powershell和脚本noob在这里 - 我甚至不知道危险。 I need to query all PCs in the domain to determine what their local Administrators group membership is and send that output to a text/csv file. 我需要查询域中的所有PC以确定其本地Administrators组成员身份是什么,并将该输出发送到text / csv文件。

I've tried numerous things like: 我尝试了很多东西,比如:

Import-Module -Name ActiveDirectory
Get-ADComputer -filter * |
Foreach-Object {
 invoke-command {net localgroup administrators} -EA silentlyContinue |
} |
Out-File c:\users\ftcadmin\test.txt

Which gets me an identical list repeated but seems to be hitting every domain PC. 这让我重复了一个相同的列表但似乎正在击中每个域PC。 I'm guessing it's not actually running on the remote PCs though. 我猜它实际上并没有在远程PC上运行。 Also tried: 还尝试过:

$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

which is limited by predetermined list of PCs in the computers.txt file. 这受到computers.txt文件中预定PC列表的限制。 A third thing I tried was this: 我试过的第三件事就是:

$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

which seems to have the most potential except the output is just 除了输出之外,它似乎最具潜力

computername1
====
computername2
====

etc without any listing of the group members. 等没有任何小组成员列表。

Any ideas from the community? 来自社区的任何想法?

Copy and paste this function into your PowerShell console. 将此功能复制并粘贴到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
        }
    }
}

Then, try this to use it: 然后,尝试使用它:

Get-ADComputer -filter * | foreach {Get-LocalGroupMember -Name 'Administrators' -ComputerName $_.Name }

If you'd like to do some formatting you could get a list of computers and have all of the members beside each one. 如果你想做一些格式化,你可以得到一个计算机列表,并在每个计算机旁边都有所有成员。

Get-ADComputer -filter * | foreach {
    $members = Get-LocalGroupMember -Name 'Administrators' -ComputerName $_.Name
    [pscustomobject]@{
        'ComputerName' = $_.Name
        'Members' = $members    
    }   
}

This requires at least PowerShell v3. 这至少需要PowerShell v3。 If you don't have that, I highly recommend upgrading to PowerShell v4 anyway. 如果您没有,我强烈建议您升级到PowerShell v4。

In powershell version 5.1, the version that comes with WMF 5.1 or Windows 10 version 1607, there are now (finally) cmdlets for managing local users and groups. 在PowerShell版本5.1(WMF 5.1或Windows 10版本1607附带的版本)中,现在(最终)有用于管理本地用户和组的cmdlet。 https://technet.microsoft.com/en-us/library/mt651681.aspx https://technet.microsoft.com/en-us/library/mt651681.aspx

For example, to get the members of the local Administrators group, you could use 例如,要获取本地Administrators组的成员,您可以使用

Get-LocalGroupMember -Group "Administrators"

Unfortunately, these new cmdlets don't have a ComputerName parameter for running the command remotely. 遗憾的是,这些新cmdlet没有用于远程运行命令的ComputerName参数。 You'll need to use something like Invoke-Command to run the command remotely and the remote computer will need to have powershell version 5.1 as well. 您需要使用Invoke-Command之类的东西远程运行命令,远程计算机也需要使用PowerShell版本5.1。

The ComputerName parameter of Invoke-Command cmdlet doesn't accept pipeline input and it only accepts strings, so we first need to expand the name property returned by Get-ADComputer and store the strings in a variable. Invoke-Command cmdlet的ComputerName参数不接受管道输入,它只接受字符串,因此我们首先需要展开Get-ADComputer返回的name属性并将字符串存储在变量中。 Thankfully the parameter accepts multiple strings, so we can simply use the $names variable in a single invoke-command call. 值得庆幸的是,该参数接受多个字符串,因此我们可以在单个invoke-command调用中使用$ names变量。 Example below: 示例如下:

$names = Get-ADComputer -Filter * | Select-Object -ExpandProperty name
Invoke-Command -ScriptBlock {Get-LocalGroupMember -Group "Administrators"} -ComputerName $names

This is actually something that I have recently worked on a fair bit. 这实际上是我最近的工作。 It seems that there are two conventional ways to get members from the local Administrators group: WMI and ADSI. 似乎有两种常规方法可以从本地Administrators组获取成员:WMI和ADSI。

In my opinion better method is to use a WMI query to get the members as this includes domain, so you know if the user/group listed is local to the server or is a domain account. 在我看来,更好的方法是使用WMI查询来获取成员,因为这包括域,因此您知道列出的用户/组是服务器本地还是域帐户。

The simpler way using ADSI does not include this information, but is less likely to get Access Denied types of errors. 使用ADSI的简单方法不包括此信息,但不太可能获得拒绝访问类型的错误。

Towards this end I have cobbled together a script that checks AD for machines that have been active in the last 30 days (if it's not online, there's no need to waste time on it). 为此,我拼凑了一个脚本,检查过去30天内活动的机器的AD(如果它不在线,则不需要浪费时间)。 Then for each of those it tries to do a WMI query to get the admin members, and if that fails it resorts to an ADSI query. 然后,对于每个人,它尝试执行WMI查询以获取管理员成员,如果失败则转向ADSI查询。 The data is stored as a hashtable since that's a simple way to manage the nested arrays in my opinion. 数据存储为哈希表,因为在我看来,这是管理嵌套数组的简单方法。

$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
}

Then you just have to output to a file if desired. 然后,您只需要输出到文件。 Here's what I would do that should output something like what you want: 这就是我要做的,应该输出你想要的东西:

$ServerHT.keys|%{"`n"+("="*$_.length);$_;("="*$_.length)+"`n";$ServerHT.$_|%{"{0}{1}" -f $(If($_.Domain){$_.Domain+"\"}), $_.Account}}

This would give you something like the following if the first two servers responded to WMI queries and the third did not: 如果前两个服务器响应WMI查询而第三个服务器没有响应,则会给出类似下面的内容:

===========
ServerSQL01
===========

ServerSQL01\SQLAdmin
TacoTruck\TMTech
TacoTruck\Stan2112

======
XWeb03
======

ChinchillaFarm\Stan2112

============
BrokenOld486
============

TMTech
Guest

That last one would trigger some red flags in my book if somebody put the Guest account in the local admin group, but I suppose that's probably one of the reason that you're doing this in the first place. 如果有人将Guest帐户放在本地管理员组中,那么最后一个会在我的书中触发一些危险信号,但我想这可能是你首先这样做的原因之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM