Script repository
The script generates a report containing subordinates of the selected user and the groups the subordinates are members of. Each subordinate will be added to the report the number of times matching the number of groups they are members of. To execute the script, create a report with a custom column of the Directory object type. The report scope should include subordinates of a user.
In the script, the $groupColumnID specifies the identifier of the custom column that will contain a group a subordinate is a 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.
$groupColumnID = "{3345fe9c-9c7d-43ab-9aee-92fb041d9091}" # TODO: modify me
$criteria = New-AdmCriteria "*"
$Context.DirectorySearcher.AddCriteria($criteria)
# Create a hash table to map group GUIDs to search results.
$guidComparer = $Context.CreatePropertyValueComparer("objectGuid")
$groupGuidToDN = New-Object System.Collections.Hashtable @($guidComparer)
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
You must be signed in to comment.