Recipient Filters Make This Easy – Or Do They?

A discussion in the Microsoft Technology Community covered some old ground when posing the question “Can a Dynamic Distribution list group be created that uses a specific SMTP domain as the filter?” On the surface, this seems like a reasonable request. Email addresses are among the set of filterable properties, so we should be all set. Properties that seem like good candidates are:

EmailAddresses                       proxyAddresses                        String (wildcards accepted).

PrimarySmtpAddress               n/a                                           String (wildcards accepted).

UserPrincipalName                 userPrincipalName                  String (wildcards accepted).

WindowsLiveID                       msExchWindowsLiveID             String (wildcards accepted).

I’ve covered the topic of creating dynamic distribution lists with complex recipient filters through PowerShell in the past. The trick is to build filters using the target properties, test the recipient filter to make sure that it finds the correct set of recipients, and then apply the filter in a dynamic distribution list.

The Problem with Wildcard Comparisons

The theory holds until you try to use email addresses in recipient filters. The difficulty is that these properties don’t work predictably (or at all) in recipient filters when searching for mail-enabled objects for email addresses belonging to a specific domain. You’d think that this would be easy because the properties all support wildcards. We should be able to use a filter like this:

$Filter = 'PrimarySMTPAddress -like "*office365itpros.com"'

However, the filter doesn’t work when tested with the Get-Recipient cmdlet using either the EmailAddresses or PrimarySMTPAddress properties. Using Get-Recipient is an excellent way of validating that a recipient filter will resolve and find mail-enabled objects from the Exchange Online directory:

Get-Recipient -RecipientPreviewFilter $Filter

Get-Recipient does work with a filter using the UserPrincipalName property, so that seems hopeful, Alas, the New-DistributionGroup cmdlet refuses to accept the filter:

$Filter = 'UserPrincipalName -like "*office365itpros.com"'

New-DynamicDistributionGroup -Name "Office365ITPros users UPN" -DisplayName "People with Office365itpros.com as UPN" -Alias O365.UPN -PrimarySmtpAddress O365.UPN@Office365itpros.com -RecipientFilter $Filter

|Microsoft.Exchange.Configuration.Tasks.ThrowTerminatingErrorException | Wildcards cannot be used as the first character. Please revise the filter criteria.

What does work is to use the property with an equal operator rather than like:

$Filter = 'UserPrincipalName -eq "*office365itpros.com"'

New-DynamicDistributionGroup -Name "Office365ITPros users" -DisplayName "People with Office365itpros.com UPN" -Alias O365.UPN -PrimarySmtpAddress O36.WindowsUPN@Office365itpros.com -RecipientFilter $Filter

The New-DynamicDistributionGroup cmdlet also works when using equal rather than like in a filter against the WindowsLiveID and EmailAddresses properties. Bizarrely, it doesn’t work for PrimarySMTPAddress. But then we discover that although it’s possible to create dynamic distribution lists with filters based on the UserPrincipalName or EmailAddresses properties, neither property works when the time comes to retrieve recipients. Retrieving the filter from the dynamic distribution list and using it with Get-Recipient doesn’t work, and neither does the background task used to calculate the list membership.

Table 1 details what happens with each of the four filterable properties I tested.

PropertyEq OperatorLike OperatorFilter works in DDL
EmailAddressesCan create DDLFailsNo
PrimarySMTPAddressFailsFailsN/A
UserPrincipalNameCan create DDLFailsNo
WindowsLiveIDWorksFailsYes
Table 1: Email address properties and recipient filters

In summary, the WindowsLiveID property is the only one that a dynamic distribution list can use in a recipient filter to find mail-enabled objects with email addresses from a specific domain. The filter only works if the domain you want to use is stored in that property. Although WindowsLiveID should hold the same value as the PrimarySMTPAddress, the two values can differ.

An Alternative Approach

Given the uncertainty around using email properties in recipient filters, it might be better to go for a solution that will work. For instance, it’s possible to use one of the fifteen custom attributes available for mailboxes and other mail-enabled objects to store the domain name and then use the custom attribute in a recipient filter.

The solution is in two parts. First, populate the attribute with the domain name (taken from the mailbox’s primary SMTP address). Second, create a dynamic distribution list for each domain with a recipient filter to find mailboxes based on the value stored in the custom attribute.

Although the solution works, its disadvantage is the ongoing requirement to populate the mailbox attribute with correct values to maintain the membership of the dynamic distribution lists. This is a task well suited to a scheduled Azure Automation runbook that can check for new mailboxes or changes to primary SMTP addresses and make appropriate adjustments.

There shouldn’t be a need to set up new dynamic distribution lists for domains after the creation of the initial set. Extra dynamic distribution lists are only needed if the organization adds new domains to the set used for the primary SMTP addresses of user mailboxes.

The Script

To prove that everything works as expected, I wrote a script (downloadable from GitHub) to scan for mailboxes that do not have the domain for their primary SMTP address stored in CustomAttribute13. The script then updates CustomAttribute13 to store the domain address.

Next, the script checks a set of predefined domains to see if a dynamic distribution list already exists for each domain. If not, the script creates a dynamic distribution list with a recipient filter to find mailboxes with the domain stored in CustomAttribute13. Here’s an extract from the script that creates the dynamic distribution lists:

ForEach ($D in $Domains) {
    $DDLAlias = ("Domain.{0}" -f $D)
    If ($Null -eq (Get-DynamicDistributionGroup -Identity $DDLAlias -ErrorAction SilentlyContinue)) {
        Write-Host ("Creating dynamic distribution list for the {0} domain..." -f $D) -ForegroundColor Yellow
        $Filter = "CustomAttribute13 -eq '$D' -and RecipientTypeDetails -eq 'UserMailbox'"
        $DDLName = ("{0} users" -f $D)
        $DDLDisplayName = ("People with {0} primary SMTP addresses" -f $D)
        $DDLPrimarySMTPAddress = ("{0}@office365itpros.com" -f $DDLAlias)
        $DDLMailTip = ("Use this distribution list to send to all users with a {0} email address" -f $D)
        # Create the new dynamic distribution list
        $DDL = New-DynamicDistributionGroup -Name $DDLName -DisplayName $DDLDisplayName -Alias $DDLAlias `
            -PrimarySmtpAddress $DDLPrimarySMTPAddress -RecipientFilter $Filter
        If ($DDL) {
            Write-Host ("Dynamic distribution list created for {0}" -f $DDLDisplayName)
            # Make sure that the dynamic distribution list has an owner
            Set-DynamicDistributionGroup -Identity $DDLAlias `
             -ManagedBy $DefaultDDLOwner -MailTip $DDLMailTip
        }
    } Else {
        Write-Host ("A dynamic distribution list already exists for {0} users" -f $D) -ForegroundColor Red
    }
}

The output is a dynamic distribution list for each domain. After giving Exchange Online some time to evaluate the recipient filter, the set of recipients is available by running a command like this:

Get-DynamicDistributionGroupMember -Identity 'Domain.office365itpros.com' | Format-Table DisplayName, PrimarySmtpAddress

DisplayName                             PrimarySmtpAddress
-----------                             ------------------
Kim Akers (She/Her)                     Kim.Akers@office365itpros.com
Ben Owens (DCPG)                        Ben.Owens@office365itpros.com
Andy Ruth (Project Director)            Andy.Ruth@office365itpros.com
James Abrahams                          James.A.Abrahams@office365itpros.com
Marc Vigneau                            Marc.Vigneau@office365itpros.com

The script works and the recipient filter generates accurate results if mailbox properties are maintained accurately. We have a solution.

Checking Email Addresses in Dynamic Entra ID Groups

In passing, it’s worth noting that Entra ID supports a rule for dynamic groups to check against email addresses. This rule finds any user account with a proxy address containing office365itpros.

(user.proxyAddresses -any (_ -contains "office365itpros"))

This is a check against a multi-value property and you cannot combine it with a check against a string property (like department or country). Nevertheless, it would be nice if Microsoft fixed recipient filters to work properly. We can but hope.

TEC Talk: Tenant-to-Tenant Power BI Migrations: The Next Frontier

TEC Talk: Tenant-to-Tenant Power BI Migrations: The Next Frontier

Join Sean Visser and Gary Hughes Free Webinar on Jan. 11th @ 11 AM EST.

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Comments

  1. james

    Hi Tony,

    Long time reader, first time poster. This post helped me solve this problem, in a different way but thank you! Old problem below…

    I’ve had a Dynamic DL snafu. The filterable properties for the RecipientFilter are quite interesting. I recently have been attempting to create a Dynamic DL that filters based off of the Database property, since this is a string (wildcards accepted) property one would think “Database -like ‘abc*'” would work. Unfortunately it doesn’t!

    Thanks again!

    1. Avatar photo
      Tony Redmond

      I wish I could help, but I don’t have an Exchange server anymore so I can’t test a DDL based on database names. I’m sure there’s a solution. It will just take some lateral thinking…

Leave a Reply