In a previous blog entry I covered how to use object filtering with the Microsoft Notes Connector. There was a reason I ran into that situation in the first place which was planning a migration from Notes to Exchange using the Notes Connector, but with a catch: I had already created new accounts in the target forest for the users in the migration scope. These accounts needed to be pre-deployed before any directory synchronization was configured so that employees in the newly acquired company could authenticate to the parent company’s AD forest and access the intranet site, among other resources. This is why I needed to limit the migration scope to the exact set of user accounts that had already been deployed in the target forest via a CSVDE import.
Normally this would not cause a problem as the directory synchronization portion of the Notes Connector can be configured to create new Contact objects instead of new User objects. Then when the mail migration tasks are performed, native or third-party tools (like Quest’s Notes Migrator or Binary Tree’s CMT Universal) can identify matching user accounts and contacts objects, merge the mail attributes into the user account, mailbox-enable it, and then delete the contact from AD. Notice I said normally. Sigh.
Introduce catch #2: The new user accounts I created in the target forest were mail-enabled. They needed to have their mail attribute (among a few others) populated with their legacy email address so that SharePoint services would import that attribute into their profile for use in the intranet site’s company directory. These items were also already acting a mail-forwarding objects and messing with them can start to open a can of worms related to X.400 addresses. When the accounts were imported in bulk, many of the legacy mail attributes were also brought it; mail-disabling them was simply not an option. This obviously presents a problem to the Connector’s directory synchronization, as it will not be able to use those in-use mail attributes since they are already entered in the user accounts, so new contacts would be created with incorrect SMTP address. That could muck-up a Global Address List in short order.
After researching the documentation and contacting Microsoft Product Support I learned that there was no native way to configure the Connector’s directory synchronization to identify the existing user objects and ‘merge’ the imported information with them. When researching a solution for this, Travis Nielsen mentioned that he had run across something similar few years prior and figured out a way to move some attributes off of the contacts created by the directory sync and stamp them onto the pre-existing objects, effectively fooling the Connector.
Knowing this, I set off to dissect how the Connector worked so that I could understand exactly what could be modified to get the end result I was looking for.
Under the Hood
In a test lab I have a target Windows 2003 forest with a separate Exchange 2003 server, and a source Windows 2003 forest with another member server running Notes/Domino 6.5.4. The Notes Connector is configured and I’ve already synchronized a handful of objects. I also have the DirSync options on the Connector set to create new Contact objects. So let’s go ahead and create a brand new user in the Notes directory to watch how directory synchronization works.
I’ve created a new user (CRusso) in the Notes directory. I’m current filtering objects with the Connector by setting the field carLicense = ‘Sync’ so then stamped that value on there, otherwise the directory sync would ignore the new user.
From the DirSync Options tab on the Connector for Lotus Notes object in the ESM, I kicked off an Immediate update from Notes to Exchange.
Checking the interactive service window on the Domino Server will show the creation of the new user, as well as the connection from the Exchange Connector:
Because an Immediate update was run, only new objects not yet identified by the Connector will be processed, hence the Documents read: 1 summary. If an Immediate Full Reload was run then all objects included in the filter scope would be read.
Flipping back to the Exchange server, the Application event log shows some recent events that tell us what the DirSync process did:
The most recent Notes Directory Synchronization event mirrors what we saw on the Domino server console:
Event Type: Information
Event Source: MSExchangeNOTES
Event Category: Notes Directory Synchronization
Event ID: 60378
Description: Directory Synchronization Export is complete. MS.DXANOTES successfully exported 1 entries, and had problems exporting 0 entries.
In addition, the two Proxy Generation events describe the stamping of mail attributes on the new contact in AD. I’ve snipped down the description to just the import part, which proxies were applied to the object.
Event Type: Information
Event Source: MSExchangeSA
Event Category: Proxy Generation
Event ID: 3006
Policy provider instance processing recipient.
Recipient DN: CN=Chris Russo,OU=Import,OU=DirSync,DC=contoso,DC=com
Proxies written to recipient:
Now we have a new contact object in the defined Import OU in Active Directory. A quick look at the E-mail Addresses tab in ADUC and we can see that we see the typical X.400 and SMTP addresses created by the RUS, as well as two Notes proxy addresses. The default (NOTES) is the address that will be used by Exchange to route email sent to this contact over the connector to the Notes directory for foreign delivery. The secondary proxy (notes) is apparently some kind of unique identifier. This attribute value will play a key role later on 😉
But if I run through the same exact process as above, only for a user which already has a user account in AD then a couple things can happen. If the user object exists in the same OU that DirSync is configured to import to, then the Connector will notice the conflict. But if the user object is in a different OU, outside what DirSync is configured to look at, then the conflict will be discovered when Exchange 2003 generates the proxy addresses on the object. Here we can see that the SMTP alias was automatically stamped with a ‘2’ suffix since the intended address is not unique.
So this is exactly the behavior we want to avoid, and ultimately have only the single user account in AD. Let’s turn our attention to the imported objects AD attributes to see what we can find.
After looking through the raw attributes of these contacts and comparing them to others, I noticed one attribute in particular that was stamped on only the contact objects created by the Connector: importedFrom. And every object had the same exact value, which is actually a unique identifier which indicates what created these objects: the Connector for Lotus Notes.
This that one of half of the puzzle, while the other half is that notes proxy address I mentioned earlier. Each AD object created by the Connector has it’s own unique value for that proxy address and I discovered it’s actually the the Person Document’s UNID in Notes.
This can be viewed in the Domino Administrator by looking at the Document Properties and clicking on the far-right tab. The first two lines make up the UNID:
When you look at the secondary notes proxy address in Active Directory on a contact object created by the Connector, we see the same UNID, but stored in a slightly different format than in Notes:
The ‘OF’ and ‘ON’ prefixes are omitted, as well as and preceding zeros, and the colons are replaced by hyphens.
ID Notes Format: OF733DCF3E:D9716911:ON862574A6:00522990
UNID AD Format: 733DCF3E-D9716911- 862574A6- 522990
Unfortunately that Notes document properties tab only displays the string, you cannot highlight and copy text from it. For a simpler way to get the UNID without typing it in manually, switch to the <+> tab and look at the end of the Identifier field, the UNID is also stored there as an alpha-numeric string:
The portion after the last forward slash is the UNID:
So to test the process I deleted the new contact object for CRusso and manually created a new user account in AD. I mail-enabled the object and set a legacy SMTP address of firstname.lastname@example.org to match the Notes account’s SMTP address. Then I manually set the importedFrom attribute, as well as added the secondary Notes proxy address. (Note that the secondary proxy address for the UNID cannot be entered in ADUC as the format is deemed invalid by the tool, it must be entered in the attribute using a raw editor, like ADSIedit.) I also updated the value in the Company Name field on the Notes Person document to have another piece of information to verify directory synchronization.
After issuing a full immediate reload on the connector I found that the primary NOTES proxy address had been added to the mail-enabled user object and the company field was also updated to reflect the change in the Notes database. Now any successive manual or scheduled directory synchronization processes will update this object as they have been associated together.
In order to complete this task at a larger scale, you would just need to export the UNID fields and NOTES mail addresses for all in-scope Notes accounts, and then use a CSV or LDIF import to create the new account in the target domain with the required information to set the foundation up for the Connector to link.
It’s also important to note that the import Container scope on the Notes Connector is able to see and search the location of any proposed targets for object matching. If you stamp the required attributes on an account stored in an OU that Connector is not configured to look at, then the matching will not work and the default action will be chosen (Create a Windows Contact object in the import container.)
Of course after I reverse engineered this process I eventually ran across a discussion online that confirmed the behavior I saw: Connector for Lotus Notes Directory Synchronization: Part 3 – Frequently Asked Questions.