Use the blue Nav bar above to access the main index pages!

List Forest-wide Active Directory Group Memberships using PowerShell

How to list a user's forest-wide group memberships in Active Directory using PowerShell.  It's not as easy as you think.  Sure, you can just get the contents of the user's memberOf attribute, but that only contains groups from the domain that the user belongs to.  What if your AD forest has multiple domains, and the user belongs to groups from more than one domain?  In that case, you have to get the user's tokenGroups attribute.

The tokenGroups attribute is a multi-valued attribute that contains a list of SIDs of the groups the user belongs to, stored as byte arrays.   The attribute is populated behind the scenes by AD.  To get the list of token groups, you first have to explicitly retrieve the contents of the attribute by calling GetInfoEX.  Then, for each token in the list, we create a security principal object that we can translate into a user name.  I toss the results into a hashtable so that I can sort the output.

The Perl version (see Enumerate TokenGroups using Perl) is slightly more complicated in that you have to convert the bytes yourself.  PowerShell does the conversion for you automatically.

$username=$args[0]
if($args.count -lt 1){
 "Usage: ./tokenGroups.ps1 <username>"
}
$groups=@{}
$gc="GC://" + $([adsi] "LDAP://RootDSE").Get("RootDomainNamingContext")
$filter = "(&(objectCategory=User)(¦(cn=" + $username + ")(samaccountname=" + $username + ")(displayName=" + $username + ")(distinguishedName=" + $username + ")))"
$domain = New-Object System.DirectoryServices.DirectoryEntry($gc)
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.SearchRoot = $domain
$searcher.Filter = $filter
$results = $searcher.FindAll()
if($results.count -eq 0){ "User Not Found"; }else{
 foreach ($result in $results){
  $user=$result.GetDirectoryEntry();
  $user.GetInfoEx(@("tokenGroups"),0)
  $tokenGroups=$user.Get("tokenGroups")
  foreach ($token in $tokenGroups){
   $principal = New-Object System.Security.Principal.SecurityIdentifier($token,0)
   $group = $principal.Translate([System.Security.Principal.NTAccount])
   $groups[$group]=1
  }
 }
}
$groups.keys ¦ sort-object

0 comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...