I recently had a customer ask why they're constantly seeing writeback to contact objects in the GalSync container, which seem to come and go without rhyme or reason. Well, there's definitely a reason, and it has to do with the way that AAD Connect does writeback of the CloudLegacyExchangeDN from Exchange Online...
Enabling Exchange hybrid write-back during the installation inserts several rules into the AAD Connect synchronization process that allow for the write-back of key Exchange attributes to the on-premises Active Directory for the purposes of rich-coexistence between the migrated mailbox in Exchange Online and the on-premises remote user mailbox which represents that cloud mailbox.
The attribute used in the hybrid write-back process that causes this problem is the ProxyAddresses attribute. If no changes are made to the default GalSync or AAD Connect configurations, both synchronization engines will attempt to make changes to the ProxyAddresses attribute values that the other server will detect and try to remove.
When GalSync creates a contact object in the target forest, it populates the ProxyAddresses attribute with all the values from the source object it represents. GalSync then manages the contact object, updating the ProxyAddresses values whenever the source object changes (ie. Addresses are added or removed). This process is uni-directional.
As a result, GalSync is considered authoritative for each contact object in the target forest, maintaining updates to the object on a regularly scheduled cycle.
The problem begins when AAD Connect is introduced into the environment, is scoped to include the OU where the GalSync solution places it’s contact objects, and Exchange Hybrid write-back is enabled as part of the AAD Connect configuration.
Once AAD Connect synchronizes the contact object to Office 365, either as-is, or joined with a user object, the cloud object is stamped with a LegacyExchangeDN value and that value is written back as an x500 address into the ProxyAddresses array of the source object. This means that AAD Connect will update every contact with one new x500 address in the ProxyAddresses array.
The next time the GalSync server scheduled synchronization process runs, it detects a change to the ProxyAddresses array (in the form of a new x500 proxy address) and because it did not write that value, it immediately removes the value from the object.
AAD Connect, on it’s next scheduled synchronization cycle, will detect that the value is gone from the contact object and will write it again.
This behavior, with the two servers battling over the values in the ProxyAddresses array of each contact object, results in a sort of ping-pong effect, constantly adding, deleting and re-adding the value as frequently as every 30 minutes.
The solution for this is to scope the writeback of contacts to exclude the GalSync OU. Fortunately the AAD Connect sync engine includes an attribute flow (in the latest versions) called OnPremisesDistinguishedName, so it can be used on the outbound scoping filter for AAD Connect…
Scoping for GalSync
Basically we need to modify the Out to AD – Contact Exchange Hybrid rule so that it only applies to contact objects that are not found in the GalSync OU. You will do this by cloning the rule as a new rule, and changing the Scoping filter so that it only applies to objects whose Distinguished Name do not contain the GalSync OU distinguished name (or part of it).
Select Outbound under the Direction dropdown in the top left of the Synchronization rule editor, locate the Out to AD – Contact Exchange Hybrid rule and click Edit.
Whenever you click Edit on a default rule, installed as part of the installation, you will be prompted to clone the rule. In this case, click Yes.
The rule will be opened for editing; the Precedence value will be set to -1, this is to ensure that the precedence value is changed before you save the new cloned rule.
Enter a value of 50 in the Precedence field, clear the description field and enter a new description indicating the reason for the rule edit and then click Next.
On the scoping filter page, click Add Group followed by Add Clause to add a single scoping filter to your newly cloned rule. In the Attribute dropdown select OnPremisesDistinguishedName, select NOTCONTAINS in the Operator dropdown and type the value GalSync in the Value field.
Alternatively, you could enter the entire Distinguished Name of the GalSync OU (eg. OU=GalSync,DC=cohovineyard,DC=us).
Finally, click Save to save your newly cloned rule.
(Note I’m using DN in the screen shot, that’s because I don’t have the latest version of AAD Connect in my lab, so I created my own attribute flow for DN. If you are using the latest version, just select OnPremisesDistinguishedName)
Once the above steps have been completed, a full synchronization of the AAD Connect solution will successfully solve the GalSync contact write-back issue.
If you prefer not to modify AAD Connect, you can use my GitHub release of Azure Aware Galsync which addresses this issue, as well as a few other’s..