Jorge's Quest For Knowledge!

All You Need To Know About Identity And Security On-Premises And In The Cloud. It's Just Like An Addiction, The More You Have, The More You Want To Have!

(2014-12-11) Finding All Direct And Indirect Members (Users) Of A Specific Group

Posted by Jorge on 2014-12-11


Sometimes you may need to retrieve all direct and indirect members of a specific group. Depending on how you query AD you get either all instances of a specific object class that are a (in)direct member of the group or you get all instances of all object classes that are a member of the group.

The first option, being "LDAP_MATCHING_RULE_IN_CHAIN" supports both and the second option "msds-memberTransitive" (only available in W2K12R2 and higher) supports only the latter.

LDAP Control 1.2.840.113556.1.4.1941 | LDAP_MATCHING_RULE_IN_CHAIN

This rule is limited to filters that apply to the DN. This is a special "extended match operator that walks the chain of ancestry in objects all the way to the root until it finds a match. The LDAP_MATCHING_RULE_IN_CHAIN is a matching rule OID that is designed to provide a method to look up the ancestry of an object. Many applications using AD and AD LDS usually work with hierarchical data, which is ordered by parent-child relationships. Previously, applications performed transitive group expansion to figure out group membership, which used too much network bandwidth; applications needed to make multiple roundtrips to figure out if an object fell "in the chain" if a link is traversed through to the end. Note that when using LDAP_MATCHING_RULE_IN_CHAIN, scope is not limited—it can be base, one-level, or subtree. Some such queries on subtrees may be more processor intensive, such as chasing links with a high fan-out; that is, listing all the groups that a user is a member of. Inefficient searches will log appropriate event log messages, as with any other type of query.

ADFIND

ADFIND -h RFSRWDC1.ADCORP.LAB -default -f "(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=group9.ls,OU=TEST,OU=Org-Users,DC=ADCORP,DC=LAB))" -dn

image

Figure 1: Example Output

AD PoSH Module

Get-ADUser -Server RFSRWDC1.ADCORP.LAB -SearchBase $((Get-ADRootDSE).defaultNamingContext) -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=CN=group9.ls,OU=TEST,OU=Org-Users,DC=ADCORP,DC=LAB)" | %{$_.DistinguishedName}

ADSI Through PoSH

$targetDC = "RFSRWDC1.ADCORP.LAB"
$rootDSE = [ADSI]"LDAP://$targetDC/RootDSE"
$defaultNamingContext = $rootDSE.defaultNamingContext
$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$Search.SearchRoot = "LDAP://$targetDC/$defaultNamingContext"
$search.filter = "(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=group9.ls,OU=TEST,OU=Org-Users,DC=ADCORP,DC=LAB))"
$search.FindAll() | %{$_.Properties.distinguishedname}

And if your DCs are already on W2K12R2, you can ALSO use the following, which basically retrieves all transitive group members of the group. As it uses the constructed attribute "msds-memberTransitive", you MUST perform a BASE search! Be aware though, that the method below gives you ALL members, independent of objectClass, while the method above allows you to target a specific objectClass as members.

ADFIND

ADFIND -h R1FSRWDC1.IAMTEC.NET -s base -b "CN=group9.ls,OU=TEST,OU=Org-Users,DC=IAMTEC,DC=NET" msds-memberTransitive

image

Figure 2: Example Output

AD PoSH Module

(Get-ADGroup -Server R1FSRWDC1.IAMTEC.NET -SearchScope Base -SearchBase "CN=group9.ls,OU=TEST,OU=Org-Users,DC=IAMTEC,DC=NET" -Filter * -Property msds-memberTransitive | Select msds-memberTransitive).’msds-memberTransitive’

ADSI Through PoSH

$targetDC = "R1FSRWDC1.IAMTEC.NET"
$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$Search.SearchRoot = "LDAP://$targetDC/CN=group9.ls,OU=TEST,OU=Org-Users,DC=IAMTEC,DC=NET"
$Search.SearchScope = "Base"
$Search.PropertiesToLoad.Add("msds-memberTransitive")
$search.FindOne() | %{$_.Properties.’msds-membertransitive’}

PS: replace the FQDN of the DC and the distinguishedName of the group with your info

Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
#########
http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: