Kae Travis

Use ADSI to List Nested Members of an AD Group (Updated)

Tags:

Other Posts in this Series:

This post includes an example of how we can use ADSI to list nested members of an AD group.  In other words, if the group contains nested groups, it will iteratively search all the members of those nested groups too.

I’ve filtered this first example to only find enabled objects for those organisations that don’t do good housekeeping!

function Find-Enabled-Members
{
    Param
    (
       [string]$DN
    )

    if (!([adsi]::Exists("LDAP://$DN"))) {
        write-host "$DN does not exist"
        return     
    }
        
    $foundCount = 0
    $group = [adsi]("LDAP://$DN")

    ($group).member | ForEach-Object {

        $groupObject = [adsisearcher]"(&(distinguishedname=$($_)))"  
        $groupObjectProps = $groupObject.FindOne().Properties
             
        if ($groupObjectProps.objectcategory -like "CN=group*") { 
            #search nested group
            $foundCount += Find-Enabled-Members "$_"            
        } else {
            $objenabled = ($groupObjectProps.useraccountcontrol[0] -band 2) -ne 2

            if ($objenabled) {
                write-host "Found $($groupObjectProps.samaccountname) in $($group.Name)"
                $foundCount += 1
            }              
        }
    }
    return $foundCount
}

#group to search for
$groupName = "Alkane_AD_Group"

$objSearcher=[adsisearcher]"(&(objectCategory=group)(name=$groupName))"
$objSearcher.PageSize = 200

#specify properties to include
$colProplist = "name","distinguishedname"
foreach ($i in $colPropList) { $objSearcher.PropertiesToLoad.Add($i) | out-null } 
	
$group = $objSearcher.FindOne()

if ($group -ne $null)
{
    #if group found

    $name = ($group.Properties).name
    $distinguishedName = ($group.Properties).distinguishedname
    
    write-host "Found group $name.  Searching members..."
    
    #find members
    $members = Find-Enabled-Members $distinguishedName
    write-host "Total enabled members including nested members is $members"
}

Since it’s checking if each member is enabled or not, it does take slightly longer to run.  If you just wanted to check the member count whether it’s disabled or enabled, you can use the following example:

function Find-Members
{
    Param
    (
       [string]$DN
    )

    if (!([adsi]::Exists("LDAP://$DN"))) {
        write-host "$DN does not exist"
        return     
    }
        
    $group = [adsi]("LDAP://$DN")

    $foundCount = $group.Member.Count

    ($group).member | ForEach-Object {

        $groupObject = [adsisearcher]"(&(distinguishedname=$($_)))"  
        $groupObj = $groupObject.FindOne()

        if ($groupObj -ne $null) {

            $groupObjectProps = $groupObj.Properties
             
            if ($groupObjectProps.objectcategory -like "CN=group*") { 

                #get path of the object from search result
                $pathToObject = ($groupObjectProps).adspath[0]

                #convert/cast search result object path to an ADSI object
                $obj = [adsi]($pathToObject)
                
                #subtract one to deduct group object (we only want to count the members)
                $foundCount = $foundCount - 1
               
                $foundCount += Find-Members "$_"         
            }
        }
    }
    return $foundCount
}

#group to search for
$groupName = "Alkane_AD_Group"

$objSearcher=[adsisearcher]"(&(objectCategory=group)(name=$groupName))"
$objSearcher.PageSize = 200

#specify properties to include
$colProplist = "name","distinguishedname"
foreach ($i in $colPropList) { $objSearcher.PropertiesToLoad.Add($i) | out-null } 
	
$group = $objSearcher.FindOne()

if ($group -ne $null)
{
    #if group found

    $name = ($group.Properties).name
    $distinguishedName = ($group.Properties).distinguishedname
    
    $members = Find-Members $distinguishedName
    write-host "Total members including nested members is $members"
}

Use ADSI to List Nested Members of an AD Group (Updated)
Use ADSI to List Nested Members of an AD Group (Updated)

Leave a Reply