Recursively Enumerating Local and AD Groups

,

If you ever need to flatten out groups which may include nested local and AD groups there’s a really easy way to do this in  the System.DirectoryServices.AccountManagement.GroupPrincipal GetMembers method. Here’s some PowerShell code which works against both local and AD groups. The code can easily be adapted into a function and in fact I’m using similar code in the SQLPSX project for SQL Server permission auditing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
add-type -AssemblyName System.DirectoryServices.AccountManagement
 
$domain = "$env:computername"
$groupname = "Administrators"
 
#Determine if domain a machine or domain
try {
    $domainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain() | select -ExpandProperty Name
    $isDomain = $domainName -match "$domain\."
}
catch {
    $isDomain = $false
}
 
if ($isDomain)
{ $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain }
else
{ $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine }
 
#Create objects to filter based on group name and ContextType--Domain or Machine
$principal = new-object System.DirectoryServices.AccountManagement.PrincipalContext $ctype,$domain
$groupPrincipal = new-object System.DirectoryServices.AccountManagement.GroupPrincipal $principal,$groupname
$searcher = new-object System.DirectoryServices.AccountManagement.PrincipalSearcher 
$searcher.QueryFilter = $groupPrincipal
 
#Note GetMembers($true) recursively enumerates groups members while GetMembers() simply enumerates group members
$searcher.FindAll() | foreach {$_.GetMembers($true)}

Rate

Share

Share

Rate