Script Repository


Members of all distribution lists

February 24, 2021
910

The script creates and emails an HTML report on members of all distribution lists in all AD domains managed by Adaxes.

To generate the reports upon request, you can create a custom command that runs the script. To schedule the reports, you need to create a scheduled task configured for the Domain-DNS object type and include any of your AD domains in the Activity Scope. To add the script to a custom command or scheduled task, use the Run a program or PowerShell script action.

Parameters:

  • $onlyDirectMembers - if set to $True, the report will include only direct members of distribution lists. If set to $False, both direct and indirect members will be included.
  • $to - Specifies a coma-separated list of recipients of the report.
  • $subject - Specifies the notification message subject.
  • $reportFooter - Specifies the report footer.
Edit Remove
PowerShell
$onlyDirectMembers = $True # TODO: modify me

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Distribution lists members report" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

function BuildGroupMemberList($filter, $memberInfos, $htmlReport, $webInterfaceAddress)
{
    # Set search parameters
    $searcher = $Context.BindToObject("Adaxes://rootDSE")
    $searcher.SearchFilter = $filter
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.SetPropertiesToLoad(@("objectGuid"))
    $searcher.VirtualRoot = $True
    
    try
    {
        # Execute search
        $searchResultIterator = $searcher.ExecuteSearch()
        $members = $searchResultIterator.FetchAll()
        
        foreach ($memberId in $members)
        {
            # Append the object to the report
            $memberName = $Context.GetDisplayNameFromAdsPath($memberId.AdsPath)
            $guid = [Guid]$memberId.Properties["objectGuid"].Value
            
            $listRecord = "<li><a href='$webInterfaceAddress`ViewObject.aspx?guid=$guid'>$memberName</a><br/></li>"
            $memberInfos.Add($guid, $listRecord)
            [void]$htmlReport.Append($listRecord)
        }
    }
    finally
    {
        # Release resources
        if ($searchResultIterator) { $searchResultIterator.Dispose() }
    }
}

if ($onlyDirectMembers)
{
    $membersProperty = "adm-DirectMembersGuid"
}
else
{
    $membersProperty = "adm-MembersGuid"
}

# Get default web interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
    $Context.LogMessage("Default web interface address not set for the Adaxes service", "Warning")
}

# Find all distribution lists
# Set search parameters
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.SearchFilter = "(&(objectCategory=group)(mailNickname=*))"
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
$searcher.VirtualRoot = $True
$searcher.SetPropertiesToLoad(@("objectGUID"))

try
{
    # Execute search
    $searchResultIterator = $searcher.ExecuteSearch()
    $groups = $searchResultIterator.FetchAll()
    
    $htmlReport = New-Object "System.Text.StringBuilder"
    $memberInfos = @{}

    foreach ($groupId in $groups)
    {
        # Add group information to the report
        $groupName = $Context.GetDisplayNameFromAdsPath($groupId.AdsPath)
        $groupGuid = [Guid]$groupId.Properties["objectGUID"].Value
        [void]$htmlReport.Append("<h3><a href='$webInterfaceAddress`ViewObject.aspx?guid=$groupGuid'>$groupName</a></h3>")
        [void]$htmlReport.Append("<ul>")
        
        # Get groups members
        $group = $Context.BindToObject($groupId.AdsPath)
        try
        {
            $memberGuidsBytes = $group.GetEx($membersProperty)
        }
        catch
        {
            [void]$htmlReport.Append("<li><b>No members</b></li></ul>")
            continue
        }
        
        # Add members to the report
        $guidsToSearch = New-Object "System.Text.StringBuilder"
        foreach ($guidBytes in $memberGuidsBytes)
        {
            $guid = [Guid]$guidBytes
            if ($memberInfos.ContainsKey($guid))
            {
                [void]$htmlReport.Append($memberInfos[$guid])
                continue
            }
            $filterPart = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("ObjectGuid", $guidBytes)
            $guidsToSearch.Append($filterPart)
        }
        
        if ($guidsToSearch.Length -ne 0)
        {
            # Build filter to find all members
            $filter = New-Object "System.Text.StringBuilder"
            [void]$filter.Append("(|")
            [void]$filter.Append($guidsToSearch.ToString())
            [void]$filter.Append(")")
            
            BuildGroupMemberList $filter.ToString() $memberInfos $htmlReport $webInterfaceAddress
        }
        [void]$htmlReport.Append("</ul>")
    }
}
finally
{
    # Release resources
    if ($searchResultIterator) { $searchResultIterator.Dispose() }
}

# Build the report
$htmlReport.Append($reportFooter)

# Send mail
$Context.SendMail($to, $subject, $NULL, $htmlReport.ToString())


Comments ( 0 )
No results found.
Leave a comment

Related Scripts