Script Repository


Group membership of user subordinates

February 15, 2022
140

The script generates a report containing subordinates of the selected user and the groups the groups the subordinates are members of. The report must have a scope of the Subordinates of type. For information on creating reports, see the Create Report tutorial.

In the script, the $groupColumnID specifies the identifier of the custom column that will contain a group a subordinates are members of. To get the identifier:

  1. In the Report-specific columns section, on the Columns tab, right-click the custom column.
  2. In the context menu, navigate to Copy and click Column ID.
  3. The column identifier will be copied to clipboard.
Edit Remove
PowerShell
$groupColumnID = "{5e237374-2f73-46dd-82b4-03251e0b3af3}" # TODO: modify me

$Context.DirectorySearcher.AppendFilter("(objectClass=*)")

# Create a hash table to map group GUIDs to search results
$guidComparer = $Context.CreatePropertyValueComparer("objectGuid")
$groupGuidToDN = New-Object System.Collections.Hashtable @($guidComparer)

# Generate report
try
{
    $searchIterator = $Context.DirectorySearcher.ExecuteSearch()
    while ($Context.MoveNext($searchIterator))
    {
        $searchResult = $searchIterator.Current
        
        # Get GUIDs of the groups
        $user = $Context.BindToObjectBySearchResult($searchResult)
        $groupGuidsBytes = $user.GetEx("adm-MemberOfGuid")
        
        $guidsToSearch = $NULL
        # Add already found objects
        foreach ($groupGuidBytes in $groupGuidsBytes)
        {
            if (-not $groupGuidToDN.Contains($groupGuidBytes))
            {
                if ($NULL -eq $guidsToSearch)
                {
                    $guidsToSearch = New-Object System.Collections.ArrayList
                }
                $guidsToSearch.Add($groupGuidBytes)
            }
            else
            {
                $groupDN = $groupGuidToDN[@(,$groupGuidBytes)][0]
                $clonedSearchResult = $searchResult.Clone($False)
                $columnValues = @{ $groupColumnID = $groupDN; }
                $Context.Items.Add($clonedSearchResult, $columnValues, $NULL)
            }
        }
        
        if ($NULL -eq $guidsToSearch)
        {
            continue
        }
        
        # Search for groups
        $groupSearcher = $Context.CreateGuidBasedSearcher($guidsToSearch)
        $groupSearcher.SetPropertiesToLoad(@("distinguishedName", "objectGuid"))
        try
        {
            $groupSearchIterator = $groupSearcher.ExecuteSearch()
            while ($Context.MoveNext($groupSearchIterator))
            {
                $groupSearchResult = $groupSearchIterator.Current
                
                # Remember the group DN
                $groupGuid = $groupSearchResult.GetPropertyByName("objectGuid").Values[0]
                $groupDN = $groupSearchResult.GetPropertyByName("distinguishedName").Values[0]
                $groupGuidToDN[$groupGuid] = $groupDN
    
                # Add the object to the report
                $clonedSearchResult = $searchResult.Clone($False)
                $columnValues = @{ $groupColumnID = $groupDN; }
                $Context.Items.Add($clonedSearchResult, $columnValues, $NULL)
            }
        }
        finally
        {
            if ($groupSearchIterator) { $groupSearchIterator.Dispose() }
        }
    }
}
finally
{
    if ($searchIterator) { $searchIterator.Dispose() }
}

Comments ( 0 )
No results found.
Leave a comment