Hello,
Thank you for the provided details. To create the report:
- Launch Adaxes Administration Console.
- In the Console Tree, right-click your service node.
- In the context menu, navigate to New and click Report.
- Enter a report name.
- Select Script and click Next.
- On the Scope page, click New.
- Select Specific Objects and click Next twice.
- Click Configure.
- In the Display only objects that match the following LDAP filter field, enter the following filter: (objectCategory=group)
- Make sure that the Allow multiple selection option is enabled and click OK.
- Click Finish.
- Click Next twice.
- In the Report-specific columns section, click Add.
- Enter a column name (e.g. Group).
- Select Active Directory object and click Next.
- Select Template.
- In the field below, enter a default value (e.g. empty). The value will never be present in the report and is only required to create the custom column.
- Click Finish.
- Select Group By and then select the custom column from the drop-down list.
- Click Next.
- Paste the below script into the corresponding field. In the script, the $groupColumnID variable specifies the identifier of the custom column that will contain groups. To get the identifier:
- On the Columns step, right-click the custom column.
- In the context menu, navigate to Copy and click Column ID.
- The column identifier will be copied to clipboard.
$groupTypes = "(&(objectCategory=group)(|(!(groupType:1.2.840.113556.1.4.803:=2147483648))(groupType:1.2.840.113556.1.4.803:=2147483648)))"
$memberTypes = "(sAMAccountType=805306368)"
$membersPropertyName = "adm-DirectMembersGuid"
# Custom column identifiers
$groupColumnID = "{f5714376-4936-49c6-a663-bb56ba8a4243}"
# IDs of primary groups to exclude from the report
$primaryGroupIDs = @{ 513="Domain Users"; 515="Domain Computers"; 516="Domain Controllers"; 521="RODCs" }
# Search filter
$filter = "(|" + $groupTypes + ")"
$Context.DirectorySearcher.AppendFilter($filter)
$filterMembers = "(|" + $memberTypes + ")"
# Add properties necessary to generate the report
$propertiesForMembers = $Context.DirectorySearcher.GetPropertiesToLoad()
$propertiesForGroups = @("objectClass", "objectGuid", "distinguishedName", "primaryGroupToken")
$Context.DirectorySearcher.SetPropertiesToLoad($propertiesForGroups)
# Create a hash table to map member GUIDs to search results
$guidComparer = $Context.CreatePropertyValueComparer("objectGuid")
$memberGuidToSearchResult = New-Object System.Collections.Hashtable @($guidComparer)
# Generate report
try
{
$searchIterator = $Context.DirectorySearcher.ExecuteSearch()
while ($Context.MoveNext($searchIterator))
{
$searchResult = $searchIterator.Current
# Exclude well-known primary groups
$primaryGroupID = $searchResult.GetPropertyByName("primaryGroupToken").Values[0]
if ($primaryGroupIDs.Contains($primaryGroupID))
{
continue
}
$groupDN = $searchResult.GetPropertyByName("distinguishedName").Values[0]
# Get GUIDs of the group members
$group = $Context.BindToObjectBySearchResult($searchResult)
try
{
$memberGuids = $group.GetEx($membersPropertyName)
}
catch [System.Runtime.InteropServices.COMException]
{
if ($_.Exception.ErrorCode -eq 0x8000500D) # E_ADS_PROPERTY_NOT_FOUND
{
# The group doesn't have any members
$columnValues = @{ $groupColumnID = $groupDN; }
if ($NULL -eq $styleNoMembers)
{
$styleNoMembers = $Context.Items.CreateItemStyle("#3d3d3d", $NULL,
"ADM_LISTITEMFONTSTYLE_REGULAR")
}
$Context.Items.Add(-1, "<No members>", "Information", $columnValues, $styleNoMembers)
continue
}
else
{
throw $_.Exception
}
}
# Add group members to the report
$guidsToSearch = $NULL
# Add already found objects
foreach ($memberGuid in $memberGuids)
{
if (-not $memberGuidToSearchResult.Contains($memberGuid))
{
if ($NULL -eq $guidsToSearch)
{
$guidsToSearch = New-Object System.Collections.ArrayList
}
$guidsToSearch.Add($memberGuid)
}
else
{
$memberSearchResult = $memberGuidToSearchResult[@(,$memberGuid)][0]
$clonedSearchResult = $memberSearchResult.Clone($False)
$columnValues = @{ $groupColumnID = $groupDN; }
$Context.Items.Add($clonedSearchResult, $columnValues, $NULL)
}
}
if ($NULL -eq $guidsToSearch)
{
continue
}
# Search for members
$memberSearcher = $Context.CreateGuidBasedSearcher($guidsToSearch)
$memberSearcher.SetPropertiesToLoad($propertiesForMembers)
$memberSearcher.AppendFilter($filterMembers)
try
{
$memberSearchIterator = $memberSearcher.ExecuteSearch()
while ($Context.MoveNext($memberSearchIterator))
{
$memberSearchResult = $memberSearchIterator.Current
# Remember the search result
$memberGuid = $memberSearchResult.GetPropertyByName("objectGuid").Values[0]
$memberGuidToSearchResult[$memberGuid] = $memberSearchResult.Clone($False)
# Add the object to the report
$columnValues = @{ $groupColumnID = $groupDN; }
$Context.Items.Add($memberSearchResult, $columnValues, $NULL)
}
}
finally
{
if ($memberSearchIterator) { $memberSearchIterator.Dispose() }
}
}
}
finally
{
if ($searchIterator) { $searchIterator.Dispose() }
}
- Click Next and finish creating the report.