Add legacyExchangeDN as x500 proxy address from a remote forest

The other day, on one of the forums, I came across an issue that I also had with one of my customers a few years ago.  In my customer's instance, they had imported thousands of contacts into an externally trusted forest and deleted them in their primary forest (which then removed the objects from Office 365).  Shockingly, they were getting NDRs in their main forest, since the internal addresses they used to resolve them were no longer available.  They had added the remote contact forest in to AAD connect, but there was no love.

To get over this, we needed to put in a custom sync rule to add the legacyExchangeDN as an x500 proxy address:

You'll want to test it in a lab, first:

  1. From the Sync Rules Editor, select Inbound under Direction.
  2. From the Sync Rules Editor, select the remote forest under Connector.
  3. Click Add New Rule.
  4. Enter a name and if you're feeling helpful to the people who come after you, a description.
  5. Under connected system, ensure that the connector for the remote forest is still selected.
  6. Choose user as Connected System object type if you're doing this for a user.  Choose contact as the Connected System object type if your'e doing this for a contact.  Choose person as the Metaverse object type in both cases.
  7. Select Join as the link type.
  8. Enter a precedence value.
  9. Click Next.
  10. In the scoping filter area, select Add Clause. Under attribute, choose legacyExchangeDN and under Operator, select ISNOTNULL.
  11. Click Next.
  12. Click Next on the Join rules page without entering anything.
  13. Add a transformation:
    type: expression
    target attribute: proxyAddresses
    source: "x500:" & [legacyExchangeDN ]
    merge type: MergeCaseInsensitive
  14. Click Add.

Here's the underlying PowerShell (if you're so enterprising):

 New-ADSyncRule `
-Name 'In from AD - User - add legacyExchangeDN to proxyAddresses' `
-Identifier [guid]::NewGuid() `
-Description '' `
-Direction 'Inbound' `
-Precedence 350 `
-PrecedenceAfter '00000000-0000-0000-0000-000000000000' `
-PrecedenceBefore '00000000-0000-0000-0000-000000000000' `
-SourceObjectType 'contact' `
-TargetObjectType 'person' `
-Connector ' [replace with appropriate AAD Connect Connector GUID] ' `
-LinkType 'Join' `
-SoftDeleteExpiryInterval 0 `
-ImmutableTag '' `
-OutVariable syncRule

Add-ADSyncAttributeFlowMapping `
-SynchronizationRule $syncRule[0] `
-Source @('legacyExchangeDN') `
-Destination 'proxyAddresses' `
-FlowType 'Expression' `
-ValueMergeType 'MergeCaseInsensitive' `
-Expression '"x500:" & [legacyExchangeDN]' `
-OutVariable syncRule

New-Object `
-TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.ScopeCondition' `
-ArgumentList 'legacyExchangeDN','','ISNOTNULL' `
-OutVariable condition0

Add-ADSyncScopeConditionGroup `
-SynchronizationRule $syncRule[0] `
-ScopeConditions @($condition0[0]) `
-OutVariable syncRule

Add-ADSyncRule `
-SynchronizationRule $syncRule[0]

You'll need to look for other inbound rules on the same connector for that object type (user, contact, group) and change their proxyAddresses merge type to MergeCaseInsensitive as well to make sure you're not overwriting one with the other. See /en-us/azure/active-directory/hybrid/concept-azure-ad-connect-sync-declarative-provisioning for more information on merge types.

Depending on what other rules you have in place, you made need to change the precedence of your rule (moving it either ahead of or behind other rules).