Share via


[ADSI] Local Groups Users, Users Type, etc ...

Question

Friday, March 16, 2012 7:30 PM

I'm having an emergency for a compliance audit they want to know who has access to a list of servers.

I found some scripts which help, but unfortunately it doesn't go as far as I need.

I need to list all the local groups, and users of a server. That what the script below does pretty well:

$server = "." # servername to query
$computer = [ADSI]"WinNT://$server,computer"

$list=@()

$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
    $group =[ADSI]$_.psbase.Path
    $group.psbase.Invoke("Members") | foreach {
        $us = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
        $list += new-object psobject -property @{Group = $group.Name;User=$us}
    }
}

$list |ft -a 

What I would like to know, is the type of each group members. So if a member is a user, I would like to see the "JohnDoe (User)", and if it is a Group I would like to see "Group1 (Group)"

What would be also nice, is to recursively expand all the groups.

Here is an output example that I would like to get

Group Member Type Users expansion
Administrators Local\User1 User
Administrators Domainy\User2 User
Administrators Local\Group1 Group List of the Group1 member
Administrators Domainx\Group2 Group List of the Group2 member
Remote Desktop Users User1 User
Remote Desktop Users Local\User5 User
Remote Desktop Users Domainx\Group3 Group List of the Group3 member

TIA

All replies (6)

Friday, March 16, 2012 7:42 PM

You could build a recursive function yourself, but I think the Quest cmdlet Get-QadGroupMember may already do what you need. Provide it the name of an AD Group, and with the -Indirect switch, it will give you all the nested members.

http://www.quest.com/powershell/activeroles-server.aspx


Friday, March 16, 2012 8:02 PM

Get-QadGroupMember works only for Domain Group, not local groups


Friday, March 16, 2012 8:24 PM

$Result = @()
foreach($server in (gc .\servername.txt)){
$computer = [ADSI](”WinNT://” + $server + “,computer”)
$Group = $computer.psbase.children.find(”Administrators”)
    function getAdmins
        {$members = $Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}
        $members}
$Result += $server
$Result += ( getAdmins )
$Result += ""
}
$Result

Try this. One of the early script which I used, require some formatting but may work for you.

Currently wrote only to check for the members of Administrator group.

Shaba


Friday, March 16, 2012 10:21 PM | 1 vote

Thanks to you guys for these fast reply, it is not perfect yet, because I have to find a way to expand the group with ADSI (I'm a Quest, and ActiveDirectory cmdlet user).

$list =@() 
$server="Server1","Server2"
$server | % {
    $server = $_
    $server
    $computer = [ADSI]"WinNT://$server,computer"
    
    $computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
        "`tGroup: " + $Group.Name
        $group =[ADSI]$_.psbase.Path
        $group.psbase.Invoke("Members") | foreach {
            $us = $_.GetType().InvokeMember("Adspath", 'GetProperty', $null, $_, $null)
            $us = $us -replace "WinNT://",""
            $class = $_.GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null)
            $list += new-object psobject -property @{Group = $group.Name;Member=$us;MemberClass=$class;Server=$server}
            "`t`tMember: $us ($Class)"
        }
    }
}   

Thursday, June 6, 2013 3:53 PM

Thanks, Cyreli for giving me something to start with.  When I ran your code, I did not get any entries for the Administrators, which was all I needed.  A few tweaks & I got what I wanted.  (Very cool learning about how to tab the output).  All I need to do is to read in a list of servers & I can produce a report for the corporate level.

$list =@() 
$server="SERVER1","SERVER2"
$server | % {
                $server = $_
                $server
$GMembers = $Null
$LocalGroup = [ADSI]"WinNT://$server.<domain>.com/Administrators,group"
$GMembers = $LocalGroup.psbase.invoke("Members") 
$GMembers | ForEach { $us = $_.GetType().InvokeMember("Adspath",'GetProperty', $null, $_, $null)
$us = $us -replace "WinNT://",""
$list += new-object psobject -property @{Server=$server}
                                                "`t $us"}
}


Wednesday, February 5, 2014 3:40 PM

HI Mike,

     I am trying to do the same , to get admin entries,

     but when i executed script you provided, i ran into below error.

Exception calling "Invoke" with "2" argument(s): "The network path was not found.
"
At D:\foreach.ps1:9 char:38

  • $GMembers = $LocalGroup.psbase.invoke <<<< ("Members")
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

You cannot call a method on a null-valued expression.
At D:\foreach.ps1:10 char:39

  • $GMembers | ForEach { $us = $_.GetType <<<< ().InvokeMember("Adspath",'GetProperty', $null, $_, $null)
        + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

Any Help here.