Recipient Filters Make This Easy – Or Do They?
Update (October 18, 2024): Microsoft announced that they will change the way that recipient filters for dynamic distribution groups work from November 30, 2024. Essentially, you can no longer use prefix wildcards against properties with the -eq operator. See this article for details.
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 O365.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.
Property | Eq Operator | Like Operator | Filter works in DDL |
EmailAddresses | Can create DDL | Fails | No |
PrimarySMTPAddress | Fails | Fails | N/A |
UserPrincipalName | Can create DDL | Fails | No |
WindowsLiveID | Works | Fails | Yes |
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.
Any other ideas since “WindowsLiveID -eq” doesn’t work anymore?
And it probably won’t work in the future. I expect to hear the formal guidance from Microsoft very soon.
Here’s a report about the changes Microsoft is making in this area: https://practical365.com/dynamic-distribution-group-wildcard/
@TonyRedmond
2 weeks ago i implemented a custom filter for DDL following the helpfull insight you provided in your article.
I used the recipientfilter {((recipienttypedetails -eq ‘usermailbox’) -and ((WindowsLiveID -eq ‘*@domain1.com’) -or (WindowsLiveID -eq ‘*@domain2.com’) – or (WindowsLiveID -eq ‘*@domain3.com’) -or (WindowsLiveID -eq ‘*@domain4.com’)))}, and the DDL worked as expected, it filtered from all the mailboxes only the ones from domain1,2,3, and 4 and contains aprox 54k members.
One week later I have tried to create another group using the recipientfilter as the one mentioned above, and something very strange happens, the newly created group which has the same filter as the one that worked, doesn’t contain any members.
Now I have tried searching online for any kind of possible explanation as to why the 2nd group doesn’t accept the same filter and came out empty handed.
Have you ever encountered something similar?
I replied in the Microsoft Technical Communmity. Basically, there might be a small error in the second DDL filter, so I suggested taking the filter that works from the first DDL and writing it into the second DDL to see what happens.
Yes I have encountered the same issue recently ..and my DDL with WindowsLiveID -eq ‘*@mydomain.com’ is not showing any results anymore
I am seeing the same issue. We have dozens of DDGs in multiple tenants that where all using a recipient filter with wildcards in it. Specifically we where using WindowsEmailAddress and it was seemingly working without issue. Only recently, since the start of August 2024, has it basically stopped working. What’s more, any updates to the groups’ recipient filter does result in the group being cleared and it never rebuilds. We have an open incident with MSFT, but they have not been as helpful as we would have hoped. I have tried testing with modifying one of our groups to use WindowsLiveID in place of WindowsEmailAddress, but it has seemingly not made any difference. It’s almost as if the process that updates DDGs is not even running properly or reading the recipient filters.
NOTE: I even tried creating a NEW DDG using WindowsLiveID in place of WindowsEmailAddress. It still did not make a difference and did not populate the new DDG. NOTE: There where NO errors displayed when using either the New or Set-DynamicDistributionGroup commandlets.
We’re checking this with the Exchange development group. It’s possible that they shipped something that broke existing DDLs. Report the problem to Microsoft and make sure that the support people understand the seriousness of the issue. Tell them that the development group is investigating.
Do you have update on this, even we are facing the same issue.
Did you report the problem to Microsoft?
Hi ! Same thing here, but I’ve noticed a difference in the ‘ldaprecipientfilter’ attribute when I do a “| fl *” on my new group. The old groups translate (msExchWindowsLiveID=*@domain.com) and the new groups by (msExchWindowsLiveID=\2a@domain.com). I think this is where the problem lies.
Best regards.
At this point, I would not update the filters defined for dynamic distribution groups that are based on email addresses until Microsoft clarifies the changes they have made. If you update a filter, it will be changed to the new filter mechanism. If you leave things alone, the defined filters will continue to work.
I understand, of course, but I’m just sharing something I’ve noticed if it helps to update the ticket and move towards resolving the problem. We’ve been dealing with this DDL problem since yesterday, after a DDL update request from our management. At first we thought we had a character encoding problem in our prompts when we saw this attribute difference 😀
Please submit a support ticket to Microsoft (if you haven’t yet already done this) to make sure that support tracks the issue and escalates to put some pressure on engineering.
I can confirm same issue for new DDLs we are trying to create. I’ve reported to MS and so far they are only telling me that my use of the recipient filter WindowsLiveID is not correct, when it has worked correctly in the past.
Hi, we just hit this issue, what about using “WindowsEmailAddress” instead?
Did you read the article? It tells you what properties can be used and which cannot.
Have you noticed that the Get-Recipient -RecipientPreviewFilter accepts wildcards for UserPrincipalName along with -like to search by email domain and returns a valid result? e.g. Get-Recipient -RecipientPreviewFilter “UserPrincipalName -like ‘*@microsoft.com’ “. Is there some way that can be used to populate the New-DynamicDistributionGroup?
Nope. This is a valid recipient filter but doesn’t work for a DDL:
New-DynamicDistributionGroup: |Microsoft.Exchange.Configuration.Tasks.ThrowTerminatingErrorException|Wildcards cannot be used as the first character.
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!
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…