Forefront Identity Manager (FIM) contains a GAL Sync MA to perform global address list synchronization between two or more AD forests hosting Exchange 2003, Exchange 2007, Exchange 2010 and last but not least Exchange 2013
Figure 1: The GAL Sync MA Within FIM
The GAL Sync MA is pre-configured for about 90% and the remaining 10% needs to be provided by you, which is environment specific information. Think about AD domains, OUs, SMTP suffixes, etc.
Another nice part about it is that it also includes code (Rules Extension DLL) to use within the GAL Sync MA and for provisioning. The Rules Extension DLL is available in the folder "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\Extensions" and is called "GALsync.dll". As soon as you configure at least one GAL Sync MA, the GAL Sync Rules Extension DLL will be configured automatically in both the metaverse and the GAL Sync MA.
Now imagine you want to change how synchronized objects are displayed in the AD forest. In other words, you want to change the Display Name of synchronized objects in the target AD forests only to include the company name of the source AD forest. This is just a example.
Besides Microsoft providing a pre-baked Rules Extension DLL, Microsoft also provides the source code to that Rules Extension DLL! The source code can be found in the folder "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\SourceCode\GalSync". My suggestion here is that if you want to recompile your own Rules Extension DLL, and therefore change the source code, you create a copy of the GalSync folder to another location on the server with the FIM Sync Engine. Be aware thought that to enough the source code, you need to use something like or similar to Visual Studio. When creating a copy of the GalSync folder, make sure to include the name of your company in the folder so that it is clear that it is custom code, e.g. GalSync_MyCompany. Of course you need to rename MyCompany to the actual name of your company.
Assuming you already have Visual Studio installed, the first thing to do is to double-click on the file "<Path>\GalSync_MyCompany\GALSync.sln". Visual Studio will start and the conversion wizard will most likely start. Accept the defaults and in the end view the conversion log.
Next thing to do is to rename the name of the solution from the default "GALSync" to "GALSync (MyCompany)". This makes it clear it is not the default source code, but rather customized. In the solution explorer right-click "Solution ‘GALSync’ (1 project)" and select rename and enter the new name name being "GALSync (MyCompany)"
Figure 2: Renaming The GAL Sync Solution
Next thing to do is to rename the name of the compiled assembly from the default "GALSync" to "GALSync_MyCompany". This makes sure that if Microsoft implements a new(er) version of the GALSync Rules Extension DLL in some service pack or hotfix, it will not break your GAL Sync solution. In the solution explorer right-click the project called "GALSync" and select properties. On the left make sure to have selected the TAB called "Application" and then enter the new assembly name being "GALSync_MyCompany". Save and close, but do not close Visual Studio!
Figure 3: Renaming The GAL Sync Assembly Name
Now, you want to change the Display Name of synchronized objects in the target AD forests only to include the company name of the source AD forest. In my test environment I only have 2 GAL Sync MAs and one company is called "ADCORP.LAB" and the other is "PARTNER.LAN". This means that every source object being synchronized such as users, groups, DLs, contacts should have the company attribute in AD populated with the name of the company.
Assuming you want to adjust every source object being synchronized such as users, groups, DLs, contacts, you need to adjust every GAL Sync MA you have created or want to create. In my environment I had to change the attribute flows in the GAL Sync MA "FOREST_ADCORP.LAB" for the yellow marked objects.
Figure 4: Adjusting The Attribute Flows For Specific Object Mappings For The MA "FOREST_ADCORP.LAB"
I also had to change the attribute flows in the GAL Sync MA "FOREST_PARTNER.LAN" for the yellow marked objects.
Figure 5: Adjusting The Attribute Flows For Specific Object Mappings For The MA "FOREST_PARTNER.LAN"
Now you are asking yourself. OK, sure, but what is the change then? Hold on, we are getting there! By default the yellow marked objects have an direct inbound attribute flow from "displayName" in the connector space to "displayName" in the metaverse. Because I want to change the Display Name of the source objects in the target AD forests I need to adjust that attribute flow. In this case I’m choosing to do the change in the inbound attribute flow. I could also have achieved the same result while doing it in the outbound attribute flow. By doing it in the inbound attribute flow I will also have the changed Display Name in the metaverse and in that case only the source GAL Sync MA needs to process the transformation while the target GAL Sync MAs just sync the value. By doing it in the outbound attribute flow every target GAL Sync MA would need to process the transformation. Remember that where you do this also depends on whether or not every target AD forest accepts this or not.
While you have that attribute flow selected, the "displayName" data source attribute will be highlighted. Change the mapping type from direct to advanced, and after that hold down the CTRL key and click on the "company" attribute and then click "Edit". As a Rules Extension FlowRule Name enter (without the quotes) "DisplayNameMapping". Now click OK and you are done, at least for ONE MA. Remember you need to do this for every yellow marked object flow rule (picture 4 and 5) in every GAL Sync MA!
Figure 6: Changing Display Name Mapping In The Inbound Attribute Flow
Now go back to Visual Studio. In the solution explorer double-click on "GALUtil.vb". Then search for "’ Object attributes". You will find the section below. Just before the line "Protected ReadOnly PROXY_ADDRESSES As String = "proxyAddresses"" add the extra lines shown below.
Figure 7: Declaring Constants For The Display Name And The Company Attribute
Protected ReadOnly DYNAMICDDL As String = "msExchDynamicDistributionList"
' Object attributes
Protected ReadOnly COMPANY As String = "company" ' CUSTOM ATTRIBUTE
Protected ReadOnly DISPLAYNAME As String = "displayName" ' CUSTOM ATTRIBUTE
Protected ReadOnly PROXY_ADDRESSES As String = "proxyAddresses"
Protected ReadOnly LEGACY_EXCHANGE_DN As String = "legacyExchangeDn"
Protected ReadOnly TARGET_ADDRESS As String = "targetAddress"
Protected ReadOnly HOME_MDB As String = "homeMDB"
Protected ReadOnly HOME_SERVER_NAME As String = "msExchHomeServerName"
Protected ReadOnly MAIL As String = "mail"
Protected ReadOnly ORGANIZATION As String = "o"
Protected ReadOnly COMMON_NAME As String = "cn"
Protected ReadOnly MAPI_RECIPIENT As String = "MapiRecipient"
In the solution explorer double-click on "GALMA.vb". Then search for "MapAttributesForImport". You will find the section below. Just after the line "Select Case FlowRuleName" and before the line "Case "TargetAddressMapping"" add the extra lines shown below.
Figure 8: Adding A New Mapping For The Display Name In The Section "MapAttributesForImport"
Public Sub MapAttributesForImport( _
ByVal FlowRuleName As String, _
ByVal csentry As CSEntry, _
ByVal mventry As MVEntry) _
If IsUnknownSourceObjectType(csentry) Then
"Unhandled object type in MapAttributesForImport called " _
& "with entry " _
& csentry.ToString & " and flow rule name " & FlowRuleName)
Select Case FlowRuleName
' CUSTOM MAPPING
Now search for "Private Sub IAFTargetAddressForUser". You will find the section below. Just before the line "Private Sub IAFTargetAddressForUser" add the extra lines shown below. This is just a location I chose.
Figure 9: Adding An Additional Section To Process The Display Name Mapping
Private Sub IAFDisplayName( _
ByVal csentry As CSEntry, _
ByRef mventry As MVEntry)
' If company attribute is present, put it in the displayName of the object
If csentry(COMPANY).IsPresent Then
mventry(DISPLAYNAME).Value = csentry(DISPLAYNAME).Value + " (" + csentry(COMPANY).Value + ")"
mventry(DISPLAYNAME).Value = csentry(DISPLAYNAME).Value
Now in the solution explorer, right-click the solution and select "Build Solution"
Figure 10: Building (Compiling) The GAL Sync Solution
Now you need to select the new Rules Extension DLL to be used in the metaverse and in every GAL Sync MA
Figure 11: Specifying The New Rules Extension DLL In the Metaverse
Figure 12: Specifying The New Rules Extension DLL In A GAL Sync MA
After synchronization, your metaverse will look similar to what is shown below, with regards to the DisplayName attribute
Figure 13: The Contents Of The DisplayName In The Metaverse
After synchronization, you’re the target AD forest "ADCORP.LAB" looks like to what is shown below, with regards to the DisplayName attribute
Figure 14: The Contents Of The DisplayName For Synchronized (Received) Contact Objects In The Target AD Forest "ADCORP.LAB"
After synchronization, you’re the target AD forest "PARTNER.LAN" looks like to what is shown below, with regards to the DisplayName attribute
Figure 15: The Contents Of The DisplayName For Synchronized (Received) Contact Objects In The Target AD Forest "PARTNER.LAN"
This is just an example of how you can change the source code for the GAL Sync solution. Of course there are all kinds of scenarios for which you may want to change the default code.
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/
############### Jorge’s Quest For Knowledge #############
######### http://JorgeQuestForKnowledge.wordpress.com/ ########