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:
- In the Report-specific columns section, on the Columns tab, right-click the custom column.
- In the context menu, navigate to Copy and click Column ID.
- The column identifier will be copied to clipboard.
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() }
}