Search code examples
powershelladmin

Local Admins report not showing domain groups


I'm trying to get the following script to export into a csv all of the local admins members and domain groups on a group of servers. It works fine to export the local admins, but I noticed that it doesn't export domain groups (ie: I have a Domain Admins group that's in the local administrators group and it doesn't show in the csv).

This is the code I have, any help would be appreciated:

param(
  [parameter(Position=0,ValueFromPipeline=$true)]
    $ComputerName=[Net.Dns]::GetHostName(),
    [System.Management.Automation.PSCredential] $Credential,
    [UInt32] $BlockSize=50
)

begin {
  $WMIEnumOpts = new-object System.Management.EnumerationOptions
  $WMIEnumOpts.BlockSize = $BlockSize

  function Get-LocalAdminGroupMember {
    param(
      [String] $computerName,
      [System.Management.Automation.PSCredential] $credential
    )
    $params = @{
      "Class" = "Win32_Group"
      "ComputerName" = $computerName
      "Filter" = "LocalAccount=TRUE and SID='S-1-5-32-544'"
    }
    if ( $credential ) {
      if ( $computerName -eq [Net.Dns]::GetHostName() ) {
        Write-Warning "The -Credential parameter is ignored for the current computer."
      }
      else {
        $params.Add("Credential", $credential)
      }
    }
    Get-WmiObject @params | ForEach-Object {
      $groupName = $_.Name
      $_.GetRelated("Win32_Account","Win32_GroupUser","","",
        "PartComponent","GroupComponent",$false,$WMIEnumOpts) | Select-Object `
          @{Name="ComputerName"; Expression={$_.__SERVER}},
          @{Name="Name"; Expression={$groupName}},
          @{Name="Member"; Expression={$_.Caption -replace "^$($_.__SERVER)\\", ""}},
          @{Name="Type"; Expression={$_.__CLASS}}
    }
  }
}
process {
$Filename = PATH HERE
$OutFileName = "C:\temp\admins.csv"

Get-Content $Filename | Foreach-Object {Get-LocalAdminGroupMember -computerName $_ | Select-Object * | Export-csv -NoType $OutFileName -Append}

Solution

  • Ah, the joys of trying to access network resources from a remote computer. You're going to lose anything that's a domain account doing what you're doing. It's jut how it works. The good news is that there's still a way to get the info you want, and you can even use Get-WmiObject to do it if you want. If you have not renamed the Administrators group (because really, who does that?), you can do this easily, but if you did and you have to look for the group by SID like you are above then you'll have to query the remote server like you are, and make adjustments with the query below with the modified name that you get back. Here's what I'd recommend doing, using the Win32_GroupUser class instead:

    Get-WmiObject -ComputerName $Server -Query "SELECT * FROM win32_GroupUser WHERE GroupComponent = ""Win32_Group.Domain='$computerName',Name='Administrators'"""
    

    To put it in place of what you have for your function, it could look something like this:

    function Get-LocalAdminGroupMember {
        param(
            [String] $computerName,
            [System.Management.Automation.PSCredential] $credential
        )
        $params = @{
            "ComputerName" = $computerName
            "Query" = "SELECT * FROM win32_GroupUser WHERE GroupComponent = ""Win32_Group.Domain='$computerName',Name='Administrators'"""
        }
        if ( $credential ) {
            if ( $computerName -eq [Net.Dns]::GetHostName() ) {
            Write-Warning "The -Credential parameter is ignored for the current computer."
            }
            else {
            $params.Add("Credential", $credential)
            }
        }
        Get-WmiObject @params | 
            Where{$_.PartComponent -match ':(.+?)\.Domain="(.+?)",Name="(.+?)"'}|
            ForEach{
                [PSCustomObject]@{
                    "ComputerName"=$computerName
                    "Name"='Administrators'
                    "Member"=$Matches[2..3] -join '\' -replace "^$computerName\\"
                    "Type"=$Matches[1]
                }
            }
    }