Complex oPath Queries and the New-EmailAddressPolicy Cmdlet
I've been working an interesting challenge this week in attempt to convert email address policies from Exchange 2003 to Exchange 2010. As part of the conversion process, LDAP queries that define the recipient filter (to which the policy will apply) need to be converted to oPath queries. In most environments, these queries are pretty simple. One policy applies to everyone. In this organization, however, each department has its own email suffix. In Exchange 2003, this was easy. Each department had its own administrative group and therefore its own legacyExchangeDN.
With the move to Exchange 2010, all departments were being consolidated. While this won't impact migrated users, it will create issues for newly created users, groups, etc. The business requirements were laid out as follows:
1. All users will be assigned a three letter department/agency code that will be written to the company attribute on the user object.
2. All mail-enabled groups must be named according to the following naming convention:
a. <Agency Code> + "DL" + [User determined name] -or-
b. <Group Scope> + "-" + <Group Type> + "-" + <Agency Code> + [User determined name]
3. All mail enabled public folders must end with "(<AGY>)" where <AGY> is the three-letter agency code for each department.
4. The primary email address for all users is firstname.lastname@agy.company.com and must be all lower case without apostrophes. Secondary email address is username@agy.comany.com.
5. Existing user mailboxes will keep their existing email addresses, as some users are grandfathered in, even though they don't explicitly match the state requirement. The email address policy is only to be applied to new users.
The first step involves differentiating the 2003 users to be migrated from new users that will be created new in 2010. New users will all be covered by the new policy. Existing mailboxes might still benefit from the policy, but must be individually evaluated to prevent mistaken overwrites. Prior to migration, the EmailAddressPolicyEnabled property is set to false on all existing mailboxes.
The second step was writing an oPath query that met the business requirements above. This was ultimately written as follows:
(
(
RecipientType -EQ 'UserMailbox' -OR
RecipientType -EQ 'MailUser' -OR
RecipientType -EQ 'linkedMailbox' -OR
RecipientType -EQ 'SharedMailbox' -OR
RecipientType -EQ 'RoomMailbox' -OR
RecipientType -EQ 'EquipmentMailbox'
)
-AND
(
company -like 'AGY*'
)
)
-OR
(
(
RecipientType -EQ 'MailUniversalDistributionGroup' -OR
RecipientType -EQ 'MailNonUniversalGroup' -OR
RecipientType -EQ 'MailUniversalSecurityGroup' -OR
RecipientType -EQ 'DynamicDistributionGroup'
)
-AND
(
DisplayName -like 'AGY DL*' -OR
DisplayName -like 'U-S-AGY*'
)
)
-OR
(
RecipientType -EQ 'PublicFolder'
-AND
DisplayName -like '*(AGY)'
)
The oPath query must be collapsed for PowerShell consumption. However, I noticed a few problems during that process. The PowerShell cmdlet didn't like references to linked, shared, room or equipment mailboxes. So, those parts of the oPath query were removed from the recipient filter attribute of the New-EmailAddressPolicy cmdlet.
The second challenge when creating the new policy cmdlets was forcing the capital letters that might exist in someone's first or last name attributes to lowercase as well as removing the apostrophe. This can actually be done with some of the same type of regular expressions as defined at https://technet.microsoft.com/en-us/library/bb232171.aspx. Granted, it's a little more complicated, but mostly just hard to read.
SMTP:%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%g.%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%r''%s@agy.company.com
Coupled with our now collapsed oPath query, we have the powershell cmdlet that builds our new policies.
New-EmailAddressPolicy -name "AGY Users" -EnabledEmailAddressTemplates "SMTP:%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%g.%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%r''%s@agy.company.com","smtp:%m@agy.company.com","X400:c=US;a= ;p=Company;o=Exchange;" -RecipientFilter {((RecipientType -EQ 'UserMailbox' -OR RecipientType -EQ 'MailUser') -AND (company -like 'AGY*')) -OR ((RecipientType -EQ 'MailUniversalDistributionGroup' -OR RecipientType -EQ 'MailNonUniversalGroup' -OR RecipientType -EQ 'MailUniversalSecurityGroup' -OR RecipientType -EQ 'DynamicDistributionGroup') -AND (DisplayName -like 'AGY DL*' -OR DisplayName -like 'U-S-AGY*')) -OR (RecipientType -EQ 'PublicFolder' -AND DisplayName -like '*(AGY)')}