Users and Local Groups Report using Powershell?

25,926

Solution 1

In fact you can with the ADSI type shortcut and the WinNT moniker. Here's an example to list groups and members from your own machine:

$server="."
$computer = [ADSI]"WinNT://$server,computer"

$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
    write-host $_.name
    write-host "------"
    $group =[ADSI]$_.psbase.Path
    $group.psbase.Invoke("Members") | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
    write-host
}

Solution 2

Powershell does not have any inherent support for such a feature. However it's easy to wrap the "net localgroup" command with a couple of powershell functions and thus enable it in the pipeline.

Get Local Groups

function Get-LocalGroups() {
  net localgroup | ?{ $_ -match "^\*.*" } | %{ $_.SubString(1) };
}

Get Local Group members

function Get-LocalGroupMembers() {
  param ([string]$groupName = $(throw "Need a name") )
  $lines = net localgroup $groupName
  $found = $false
  for ($i = 0; $i -lt $lines.Length; $i++ ) {
    if ( $found ) {
      if ( -not $lines[$i].StartsWith("The command completed")) {
        $lines[$i]
      }
    } elseif ( $lines[$i] -match "^----" ) {
      $found = $true;
    }
  }
}

Solution 3

Below is an improved version of Shay Levy's script which works for local groups with "orphaned" accounts which SIDs can't be resolved.

$server = "$env:COMPUTERNAME"
$computer = [ADSI]"WinNT://$server,computer"

$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
    write-host $_.name
    write-host "------"
    $group =[ADSI]$_.psbase.Path
    $group.psbase.Invoke("Members") | foreach {$_."GetType".Invoke().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
    write-host
}

Solution 4

Jay Levy's answer turned into a function :)

Function Get-LocalGroupMembers
{
    Param(
        [string]
        $server = "."
    )
    Try
    {
        $computer = [ADSI]"WinNT://$( $Server ),computer"
        $computer.psbase.children | 
            where { 
                $_.psbase.schemaClassName -eq 'group' 
            } |
                ForEach {
                    $GroupName = $_.Name.ToString()
                    $group =[ADSI]$_.psbase.Path
                    $group.psbase.Invoke("Members") |
                        foreach {
                            $memberName = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) -replace "WinNT:", ""

                            $props = @{
                                "LocalGroup" = $GroupName
                                "MemberName" = $memberName
                            }

                            $obj = New-Object -TypeName psobject -Property $props
                            Write-Output $obj
                        } # foreach members
                } # foreach group
    }
    Catch
    {
        Throw
    }
}

To get the local group members

Get-LocalGroupMembers

To get the local group members for another machine

Get-LocalGroupMembers -Server $Computer
Share:
25,926
Admin
Author by

Admin

Updated on April 18, 2020

Comments

  • Admin
    Admin about 4 years

    Is there a simple way using powershell to show all Local Windows Groups that are active on a machine and the users that are part of those groups? A second part of this question would be if it can be extended to look at more than one machine at a time.

  • msvcyc
    msvcyc almost 15 years
    I am getting an error with the statement $group =[ADSI]$_.Path
  • Shay Levy
    Shay Levy almost 15 years
    add psbase in front of path (i.e. [ADSI]$_.psbase.Path)
  • Loïc MICHEL
    Loïc MICHEL over 11 years
    omg thank you i would have never found this myself ! Is there a way to know if the members of the localgroup are user or group ? (i want to list members of the localgroup administrators and if a member is a domaingroup list its members )
  • Shay Levy
    Shay Levy over 11 years
    I guess you can , try querying the groupType property, it only exist for groups.
  • bradvido
    bradvido over 10 years
    The loop should break once it hits the line "The command completed", otherwise it will return an empty string as the last element of the array because the last line in the output is blank.
  • Safor
    Safor almost 9 years
    $_.GetType() will fail for 'orphaned' SIDs (unresolved accounts)
  • Safor
    Safor almost 9 years
    In case of unresolved accounts you get the following error: Error while invoking GetType. Could not find member. + ... | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $ ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], MissingMemberException + FullyQualifiedErrorId : System.MissingMemberException
  • salvationishere
    salvationishere over 6 years
    How do I edit this script to output the results to a text or csv file?
  • salvationishere
    salvationishere over 6 years
    How do I edit this function to output the results to a text or csv file?