Using Microsoft Identity Manager Synchronisation Server’s Global Address List Synchronisation feature to create a shared global address book across three Exchange Forests

Introduction

Over the life of a company, there can be many acquisitions and mergers. During such events, the parent and the newly acquired entities have their IT “merged”. This allows for the removal of redundant systems and the reduction of expenses. It also fosters collaboration between the two entities. Unfortunately, the marriage of the two IT systems, can at times, take a long time.

To enable a more collaborative space between the parent and the newly acquired company, a shared “global address book” can be created, which will allow employees to quickly look up each others contact details easily.

In this blog, I will show how we can use Microsoft Identity Manager (MIM) 2016 Synchronisation Server’s  GALSync feature to extend the Global Address Book (GAL) of three Exchange Forests. The GAL will be populated with contacts corresponding to  mailboxes in the other Exchange Forests, and this will be automatically maintained, to ensure the contacts remain up-to-date.

Though this blog focuses on three Exchange Forests, it can easily be adapted for two Exchange Forests, if you remove all reference to the third AD Forest, AD Domain and Exchange Forest

For reference, we will be using the following:

Name: Contoso Limited (parent company)
Active Directory Forest: contoso.com
Active Directory Domain: contoso.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: CEX01.contoso.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: contoso.com, contoso.com.au
Number of employees: 2000

Name: Northwind Traders (newly acquired)
Active Directory Forest: northwind.com
Active Directory Domain: northwind.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: NWEX01.northwind.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: northwind.com, northwind.com.au
Number of employees: 400

Name: WingTip Toys (newly acquired)
Active Directory Forest: wingtiptoys.com
Active Directory Domain: wingtiptoys.com
Active Directory Forest Level: Windows Server 2008 R2
Exchange Server FQDN: WTTEX01.wingtiptoys.com
Exchange Server Version: Exchange 2010 SP3
Email Address Space owned: wingtiptoys.com, wingtiptoys.com.au
Number of employees: 600

 

Contoso, Northwind and WingTip Toys are connected using a wide area network and it has been decided that the MIM Synchronisation Server will be installed and configured in the the Contoso domain.

Preparation

Before we start, some preparation work has to be done to ensure there are no roadblocks or issues.

  • Cleanup of “inter forest” email objects
    • This is one of the most important things that must be done and I can’t stress this enough. You will have to go through all your email objects (mailboxes, contacts, mailuser objects) in each of the three Exchange Forests (Contoso, Northwind, WingTip Toys) and find any that are forwarding to the other Exchange forests. If there are any, these must be removed. GALSync will create email enabled contacts corresponding to the mailboxes in the other Exchange Forests, with  externalemailaddress of these new objects set to the primary email address of the other Exchange Forest’s objects. If duplicates arise because there were existing objects in the local Exchange Forest corresponding to the other Exchange Forest’s objects, this will cause the local Exchange Server to get confused and it will keep on queuing emails for these objects and will not deliver them [if after implementing GALSync, some users complain about not receiving emails from a certain Exchange Forest, this could be a possible reason]
  • Creation of Organisational Units (OU) that will be used by GALSync
    • Create the following Organisational Units in the three Active Directory domains
      • contoso.com\GALSync\LocalForest\Contacts
      • contoso.com\GALSync\RemoteForest\Contacts
      • northwind.com\GALSync\LocalForest\Contacts
      • northwind.com\GALSync\RemoteForest\Contacts
      • wingtiptoys.com\GALSync\LocalForest\Contacts
      • wingtiptoys.com\GALSync\RemoteForest\Contacts
  • Service Accounts
    • The following service accounts must be created in the specified Active Directory domains. You can change the name to comply with your own naming standards
      • MIM Synchronisation Server Service Account
        • UPN: svc-mimsync@contoso.com
        • AD Domain to create in: contoso.com
        • Permissions: non-privileged Active Directory service account
      • Management Agent Account to connect to Contoso.com AD Domain
        • UPN: svc-mimadma@contoso.com
        • AD Domain to create in: contoso.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the Contoso AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within the GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange Organization Management Active Directory security group in Contoso AD Domain
      • Management Agent Account to connect to Northwind.com AD Domain
        • UPN: svc-mimadma@northwind.com
        • AD Domain to create in: nothwind.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the Northwind AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange Organization Management Active Directory security group in Northwind AD Domain
      • Management Agent Account to connect to WingTiptoys.com AD Domain
        • UPN: svc-mimadma@wingtiptoys.com
        • AD Domain to create in: wingtiptoys.com
        • Permissions
          • non-privilged Active Directory service account
          • Grant “Replicating Directory Changes” permission
          • Grant the following permissions on the GALSync OU in the WingTipToys AD Domain that was created above. Ensure the permissions propagate to all sub-OUs within GALSync OU
            • Create Contact Objects
            • Delete Contact Objects
            • Read all Properties
            • Write all Properties
          • Add to the Exchange Organization Management Active Directory security group in Northwind AD Domain
      • Service account used for the scheduled task job that will run the MIM RunProfiles script on the MIM Synchronisation Server
        • UPN: svc-mimscheduler@contoso.com
        • AD Domain to create in: Contoso.com (this can also be a local account on the MIM Synchronisation Server)
        • Permissions
          • non-privileged Active Directory service account
          • Grant “Log on as a batch job” user right on the MIM Synchronisation Server
          • Add to FIMSyncOperators security group on the MIM Synchronisation Server (this security group is created locally on the MIM Synchronisation Server after MIM Synchronisation Server has been installed)
  • SQL Server Permissions
    • MIM Synchronisation Server requires a Microsoft SQL Server to host its database. On the SQL Server, grant SQL SYSADMIN role to the account that you will be logged on as when installing MIM Synchronisation Server

Configuration

Provision a Microsoft Windows Server 2012 R2 in the Contoso.com Active Directory domain and install MIM 2016 Synchronisation Server. During installation, specify svc-mimsync@contoso.com as the account under which the MIM Synchronisation Service will run.

One thing to note is that GALSync will update the proxyaddress field for all mailboxes in its scope (mailboxes for which it will be creating contacts in the other Exchange Forests) with X500 entries.

Management Agent Configuration

  1. Once the MIM Synchronisation Server has been successfully installed, use the following steps to create the GALSync Management Agents. Open the Synchronisation Service Manager
    • Create GALSync Management Agent for Contoso.com AD Forest
      • From Tools menu, click Management Agents and then click Create
      •  In the Management Agent drop-down list, click Active Directory global address list (GAL) 
      • In the name type GALSyncMA for Contoso.com
      • On the Connect to an Active Directory Forest page, type the forest name, the MIM MA account details (svc-mimadma@contoso.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside contoso.com\GALSync (this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select Contoso.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Northwind and WingTipToys Exchange Forest
        • Source Container select Contoso.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to Contoso.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Northwind and WingTipToys AD Domain (personally, I haven’t seen any objects created in this OU)
      • In Exchange Configuration click Edit and enter all the email suffixes that belong to Contoso.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @contoso.com and @contoso.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions section. One thing I would like to mention here is that in Configure Connection Filter section, the Filter Type for user is supposed to be Declared (and is the default setting), not Rules extension as stated in https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the Configure Extensions section, set the following
      • Click OK
    • Create GALSync Management Agent for Northwind.com AD Forest
      • From Tools menu, click Management Agents and then click Create
      •  In the Management Agent drop-down list, click Active Directory global address list (GAL) 
      • In the name type GALSyncMA for Northwind.com
      • On the Connect to an Active Directory Forest page, type the forest name, the MIM MA account details (svc-mimadma@northwind.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside northwind.com\GALSync (this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select Northwind.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Contoso and WingTipToys Exchange Forest
        • Source Container select Northwind.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to Northwind.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Contoso and WingTipToys AD Domain (personally, I haven’t seen any objects created in this OU)
      • In Exchange Configuration click Edit and enter all the email suffixes that belong to Northwind.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @northwind.com and @northwind.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions section. One thing I would like to mention here is that in Configure Connection Filter section, the Filter Type for user is supposed to be Declared (and is the default setting), not Rules extension as stated in https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the Configure Extensions section, set the following
      • Click OK
    • Create GALSync Management Agent for WingTipToys.com AD Forest
      • From Tools menu, click Management Agents and then click Create
      •  In the Management Agent drop-down list, click Active Directory global address list (GAL) 
      • In the name type GALSyncMA for WingTipToys.com
      • On the Connect to an Active Directory Forest page, type the forest name, the MIM MA account details (svc-mimadma@wingtiptoys.com) and the domain name
      • In the next screen, specify the OUs that GALSync will query to find mailboxes to create contacts for in the other forests. Also, place a tick beside wingtiptoys.com\GALSync (this selects GALSync and all sub-OUs)
      • In the Containers screen, for
        • Target Container select WingTipToys.com\GALSync\RemoteForest\Contactsthis is the OU where MIM GALSync will create contacts corresponding to the mailboxes in Contoso and Northwind Exchange Forest
        • Source Container select WIngTipToys.com\GALSync\LocalForest\Contactsthis is where MIM GALSync will create contacts corresponding to WingTipToys.com mailboxes. These will be sent to the GALSync/RemoteForest/Contacts OU in Contoso and Northwind AD Domain (personally, I haven’t seen any objects created in this OU)
      • In Exchange Configuration click Edit and enter all the email suffixes that belong to WingTipToys.com. The email suffixes listed here are used to filter out which email addresses from the original email object are added to the corresponding contact in the other Exchange Forests. In this case the email suffixes will be @wingtiptoys.com and @wingtiptoys.com.au. Note the @ before the email suffix)
      • Leave everything else as default and proceed to the Configure Extensions section. One thing I would like to mention here is that in Configure Connection Filter section, the Filter Type for user is supposed to be Declared (and is the default setting), not Rules extension as stated in https://technet.microsoft.com/en-us/library/cc708642(v=ws.10).aspx
      • In the Configure Extensions section, set the following
      • Click OK
  2. Enable provisioning by using the following steps
    • In the Synchronisation Service Manager, from Tools select Options
    • Under Metaverse Rules Extensions ensure the following have been ticked
      • Enable metaverse rules extensions
      • Enable Provisioning Rules Extension

Run Profiles Execution Order

Congratulations! All configuration has now been completed. All we have to do now is to run the synchronisation jobs to get the mailbox object information from the three AD Forests into the MIM metaverse, let MIM GALSync do a bit of processing to find out which contacts are to be created in the other Exchange Forests, and then carry out an export, to create those contacts in the other Exchange Forests. Unfortunately, MIM has no way of finding out if the exports were successful, and that is why we will have to do a confirming import on all the management agents, so that MIM can find out if everything had been exported as expected.

From my testing, I have found that when MIM GALSync does its processing, it compares the mailboxes that an Exchange Forest has with what is in the MIM metaverse. MIM then exports out, as contacts, all objects that are in the metaverse but not in that particular Exchange Forest. These are populated in that AD Domains GALSync/RemoteForest/Contacts OU as AD objects and subsequently mail enabled using the Exchange RPS URI (remote PowerShell url)

CAUTION! Before you continue, you need to find out if a synchronisation solution had previously been deployed in the environment.

If any of the AD Forests had previously had a synchronisation solution deployed, then we will need to follow the run profile execution order mentioned below. This is done to ensure no duplicate contacts are created during the initial GAL synchronisation.

  1. Full Import (Staging Only) on GALSyncMA for Contoso.com
  2. Full Import (Staging Only) on GALSyncMA for Northwind.com
  3. Full Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Delta Synchronisation on GALSyncMA for Contoso.com
  5. Delta Synchronisation on GALSyncMA for Northwind.com
  6. Delta Synchronisation on GALSyncMA for WingTipToys.com
  7. Repeat Delta Synchronisation on GALSyncMA for Contoso.com
  8. Repeat Delta Synchronisation on GALSyncMA for Northwind.com
  9. Repeat Delta Synchronisation on GALSyncMA for WingTipToys.com
  10. Export on GALSyncMA for Contoso.com
  11. Export on GALSyncMA for Northwind.com
  12. Export on GALSyncMA for WingTipToys.com
  13. Delta Import on GALSyncMA for Contoso.com
  14. Delta Import on GALSyncMA for Northwind.com
  15. Delta Import on GALSyncMA for WingTipToys.com

 

If there hasn’t been any previous synchronisation solutions deployed in any of the AD Forests, then use the following runprofile order for the initial run

  1. Full Import (Staging Only) on GALSyncMA for Contoso.com
  2. Full Import (Staging Only) on GALSyncMA for Northwind.com
  3. Full Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Full Synchronisation on GALSyncMA for Contoso.com
  5. Full Synchronisation on GALSyncMA for Northwind.com
  6. Full Synchronisation on GALSyncMA for WingTipToys.com
  7. Export on GALSyncMA for Contoso.com
  8. Export on GALSyncMA for Northwind.com
  9. Export on GALSyncMA for WingTipToys.com
  10. Delta Import on GALSyncMA for Contoso.com
  11. Delta Import on GALSyncMA for Northwind.com
  12. Delta Import on GALSyncMA for WingTipToys.com

 

Once the initial synchronisation has completed, you will see contacts in each AD Domain’s GALSync\RemoteForest\Contacts OU corresponding to mailboxes in the other two Exchange Forests. These will have been email enabled and will show in the Exchange console and the online Global Address List.

Outlook clients that use offline address books won’t see the new contacts until the offline address book generation process has run on the Exchange servers and the updated offline address book has been downloaded by the outlook client.

To ensure the GALSync generated contacts remain up-to-date, the following runprofile execution order must be used from hereon. This should be repeated every 1 hour (or as per your required interval. Keep in mind that if after one cycle of the following order, if anything is still pending an Export, then this will be run at the next runprofile execution, so changes might not be seen for at most two runcycle intervals)

  1. Delta Import (Staging Only) on GALSyncMA for Contoso.com
  2. Delta Import (Staging Only) on GALSyncMA for Northwind.com
  3. Delta Import (Staging Only) on GALSyncMA for WingTipToys.com
  4. Delta Synchronisation on GALSyncMA for Contoso.com
  5. Delta Synchronisation on GALSyncMA for Northwind.com
  6. Delta Synchronisation on GALSyncMA for WingTipToys.com
  7. Export on GALSyncMA for Contoso.com
  8. Export on GALSyncMA for Northwind.com
  9. Export on GALSyncMA for WingTipToys.com
  10. Delta Import on GALSyncMA for Contoso.com
  11. Delta Import on GALSyncMA for Northwind.com
  12. Delta Import on GALSyncMA for WingTipToys.com

I don’t imagine anyone would want to run the runprofiles manually every hour 😉 So below is a script that can be used to do it.

Export all the runprofiles using the Synchronisation Service Manager as vbs scripts and place them in a folder c:\scripts\runprofiles on the MIM Synchronisation Server.

Copy the below script and save it as GALSync_RunProfiles.cmd in c:\scripts

@echo off
REM This script will run the MIM RunProfiles in the correct order
REM Author nivleshc@yahoo.com

set _script_dir="c:\scripts\runprofiles\"

REM Delta Import (Stage Only)
echo ContosoGALSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Import_StageOnly.vbs

echo NorthwindGALSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Import_StageOnly.vbs

echo WingTipToysGAlSyncMA Delta Import -StageOnly
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Import_StageOnly.vbs

REM Delta Sync
echo ContosoGALSyncMA Delta Sync
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Sync.vbs

echo NorthwindGALSyncMA Delta Sync
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Sync.vbs

echo WingTipToysGAlSyncMA Delta Sync
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Sync.vbs

REM Export
echo ContosoGALSyncMA Export
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Export.vbs

echo NorthwindGALSyncMA Export
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Export.vbs

echo WingTipToysGAlSyncMA Export
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Export.vbs

REM Delta Import
echo ContosoGALSyncMA Delta Import
CSCRIPT //B %_script_dir%ContosoGALSyncMA_Delta_Import.vbs

echo NorthwindGALSyncMA Delta Import
CSCRIPT //B %_script_dir%NorthwindGALSyncMA_Delta_Import.vbs

echo WingTipToysGAlSyncMA Delta Import
CSCRIPT //B %_script_dir%WingTipToysGAlSyncMA_Delta_Import.vbs

 

Create a scheduled task on the MIM Synchronisation Server to run GALSync_RunProfiles.cmd script every 1 hour (or for an interval of your choice). Use the task scheduler account that had been created during the preparation stage to run this scheduled task.

Some Gotchas

I have found that sometimes some mailboxes fail to be imported into the MIM Metaverse and report an mv-constraing-restriction violation on the msExchSafeSenderHash attribute. This error occurs because the AD attribute msExchSafeSenderHash is much longer than what the corresponding MIM Metaverse attribute is. Since this attribute is not being used to create the contacts in the other Exchange Forests, it can be dropped from the attribute flow.

Use the steps outlined in the following article to resolve this issue. https://social.technet.microsoft.com/wiki/contents/articles/10733.troubleshooting-galsync-mv-constraint-violation-msexchsafesenderhash.aspx

 

I hope this blog helps those that might be wanting to create a shared “global address book” among multiple Exchange Forests.

As mentioned previous, the above steps can be used to create a  shared “global address book” for two Exchange Forests as well. In that case, just remove any mention of the third AD Forest, AD Domain and Exchange Forest from the above mentioned steps.

Enjoy 😉

 

Advertisements

Continuous Credential Prompt when accessing MIM Password Registration Portal

Recently I was at a customer site, setting up a Microsoft Identity Manager (MIM) 2016 environment, which included the deployment of the Self Service Password Registration and Self Service Password Reset portals. For additional security, I was using Kerberos instead of the default NTLM.

I finished installing the MIM Portal, Service, Password Registration and Password Reset Portals without any issues.

I then proceeded to securing all http endpoints by enabling them for SSL and after that removing the http bindings, so that you could access the MIM Portal, Password Registration and Password Reset Portals only via https. No issues there as well.

By this time I was pretty pleased with myself 😉 Everything was going as planned, no issues faced at all. Finally, lady luck was showering me with her blessings.

Having finished the installation and configuration, I proceeded to testing the solution.

The first thing to check was the MIM Portal site. I opened up a web browser and navigated to the Microsoft Identity Manager Portal. When prompted, I logged in with the mimadmin domain account credentials. I was successfully logged in and could access all the parts without any hitch.

Now kids, if you are faint at heart, be very wary of what happens next (hint. this is the time when you cover your eyes with your hands when watching a horror movie).

I then tried accessing the Self Service Password Registration Portal and got prompted for credentials.

SSPRegistration_CredentialPrompt

I entered the mimadmin account credentials and pressed enter. Just as I thought I had successfully logged in, the credential prompt returned! hmm, that is weird. I was pretty sure I had typed the username and password correctly. Oh well, maybe I didn’t.

I typed the credentials again and pressed enter. Quick as a flash, the credential prompt returned! Uh? What was happening here?{scratching my head} Hmm, I seem to be making a lot of typos today. I carefully entered the username and password again, taking my time this time, to ensure I was entering it correctly. I then pressed enter and waited.

Well, I didn’t have to wait for long since within a second, I got greeted with the Not Authorized screen!

SSPRegistration_NotAuthorised

Fascinating. It seems that lady luck had flown away because here indeed was an issue with the Self Service Password Registration Portal! Ok, Mister. Lets have a look at whats causing this kerfuffle!

I opened up the event viewer on the Self Service Password Registration server and went through each of the logged events in the Application and System logs, however I couldn’t find any clue as to why the credentials were not working. I secretly had suspicions that the issue could be due to Kerberos token errors, however I couldn’t find anything in the event logs to substantiate my suspicion. Hmm, the plot was indeed getting thicker!

I next started doing some Google searches, thinking that someone else might have encountered the same issue. Alas, it seemed that I was alone in my woes as the results seemed to be quite thin in regards to any possible solution for my issue.

Finally, I decided to follow my dear ol’ Sherlock’s advice “when you have eliminated the impossible, whatever remains, however improbable, must be the truth”

I went through the whole Self Service Password Registration setup process, checking each and every part of the configuration, to ensure that the values were as expected. After 10 minutes, I was almost done checking and no clues so far 😦

Lastly, I opened IIS Manager and checked all the settings. Nothing here as well. Hey back up a bit. What is this?

The Self Service Password Registration Portal site had its useAppPoolCredentials set to False.

SSPRegistration_useAppPoolCredentialsFalse

Now, this should be True! Is this what was causing the issue?

I quickly changed the value for useAppPoolCredentials from False to True.

SSPRegistration_useAppPoolCredentialsTrue

I then opened my web browser again and navigated to the Self Service Password Registration Portal. Once again the familiar credential prompt came up. I entered the same credentials as before and pressed enter.

Woo hoo!! This time around I was successfully logged in.

I sincerely hope that this post helps others who might be encountering the same error.

Have a great day 😉

 

MfaSettings.xml updates not taking effect

Last week, I was at a client site, extending their Microsoft Identity Manager (MIM) 2016 Self Service Password Reset Solution so that it could use Azure MultiFactor Authentication (MFA). This is an elegant solution since instead of using Questions and Answers to authenticate yourself when trying to reset your password, you can use One Time Passwords (OTP), sent as a security code via a text message to your registered mobile device.

I followed the steps as outlined in https://github.com/Microsoft/MIMDocs/blob/master/MIMDocs/DeployUse/working-with-self-service-password-reset.md to enable Azure MFA, and everything went smoothly.

I then proceeded to testing the solution.

Using the Password Registration Portal, I registered my mobile number against my test user account.

I then opened the Password Reset Portal, entered my test user username and proceeded to wait for the text message from Microsoft Azure with the security code, so that I could enter it in the next screen.

MIM_Verify_MobilePhoneVerification

I waited and waited (for at least 5 min), unfortunately the text message didn’t arrive 😦

Ok, troubleshooting time.

On my Microsoft Identity Manager 2016 Service Server, I opened the Windows EventLogs viewer and then expanded the section for Forefront Identity Manager event logs. Aha, I was on the right track as I saw a lot of errors reported.

MIMServiceServer_EventLogs

I went through the event log entries and found one which looked abit odd. The error essentially said that the certificate path contained illegal characters.

MIMServiceServer_Error_CertificatePath

I couldn’t make much sense of this error, so I opened the MfaSettings.xml file to check, and I quickly realised my mistake. I had included the certificate file path within quotes!

I quickly removed the unnecessary ” “ , saved the MfaSettings.xml file and restarted my testing process.

I went through the password reset process again, and yet again, I didn’t receive any text message from Microsoft Azure with the security code 😦

I re-checked the eventlogs and noticed the same Exception: Illegal characters in path for the Certificate File Path error. Thinking that I might have forgotten to save the previous modification to the MfaSettings.xml file, I opened the file to confirm. The quotes were no where to be seen! Alas, the plot thickens my dear Watson!

I couldn’t find any explanation for this behaviour. Then, thinking that maybe the MIM server was having issues accessing the long filepath for the Certificate file, I moved the certificate file to a folder that was closer to the root of the C:\ drive, updated the MfaSettings.xml file appropriately and repeated my testing.

Again, no text message 😦

Checking the event logs, I noticed the same dreaded Exception: Illegal characters in path for the Certificate File Path error again.

However, looking closer at the error, I realised that the file path was reported as C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\MfaCerts\cert_key.p12, which wasn’t correct since I had moved the certificate file to another folder and updated the MfaSettings.xml file accordingly!

Suddenly I had that light bulb moment 😉 Updates to the MfaSettings.xml file were not being read by the MIM Server! This could only mean that it wasn’t monitoring this file for any changes, quite the opposite to what I had initially assumed!

To force MIM to re-read the MfaSettings.xml file, I restarted the Forefront Identity Manager Service service and went through my password reset testing process again.

Eureka! This time around, I received the text message from Microsoft Azure with the security code! Checking the Event logs, I couldn’t find any new occurrences of the Exception: Illegal characters in path for the Certificate File Path error. Hurray!

I completed the password reset process and confirmed that the password for my test account had indeed been changed.

I hope this post helps others.

BTW, below is a sample of the MFASettings.xml file (for security reasons, the keys have been scrambled, however as seen below, none of the values need quotes)

<?xml version=”1.0″ encoding=”utf-8″ ?>
<SubscriberKeys>
<LICENSE_KEY>1A3FED2C1BZA</LICENSE_KEY>
<GROUP_KEY>a1b234c567890e123456gh1234567eij</GROUP_KEY>
<CERT_PASSWORD>1ABDCDEF1GHDAVWA</CERT_PASSWORD>
<CertFilePath>C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\MfaCert\cert_key.p12</CertFilePath>
<Username>john.doe</Username>
<DefaultCountryCode>61</DefaultCountryCode>
</SubscriberKeys>

 

Error rebuilding MIMWAL – File MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.dll not found

A few days ago, I was going through the steps for compiling MIMWAL, as listed at http://ithinkthereforeidam.com/installing-the-mimwal/ and came across an interesting problem.

After I had rebuilt my Visual Studio package, I went to run Sign.cmd and kept getting the following error message

MicrosoftServicesIdentityManagementWorkflowActivityLibraryNotFound

Error: File “MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.dll” Not Found. You need to compile WAL solution first! Make sure you use REBUILD Solution menu. Aborting script execution…

This was quite bizarre as I had not deviated from the steps listed in the above mentioned article. It was time to put on my Sherlock hat and find the culprit behind this error!

I opened the SolutionOutput folder and compared the contents to what was shown in the article and found something interesting. The dll mentioned in the error was indeed missing!

Also the file MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.pdb was missing.

This meant that there must have been an error when rebuilding the package in Visual Studio. I alt+tabbed to my Visual Studio screen and in the output pane, saw something interesting. It showed that there had been some issues while copying  MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.dll to the SourceOutput folder.

VisualStudioOutputPane_Error

The error

WorkflowActivityLibrary -> C:\MIMWAL-2.16.1028.0\src\WorkflowActivityLibrary\bin\Release\MicrosoftServices.IdentityManagement.WorkflowActivityLibrary.dll
1> Does C:\MIMWAL-2.16.1028.0\src\SolutionOutput specify a file name
1> or directory name on the target
1> (F = file, D = directory)? ?

seemed to indicate that when Visual Studio was trying to copy the two missing files, it hadn’t been able to determine if the destination folder  SourceOutput was a directory or a file. This resulted in Visual Studio skipping the copy of these files. Doing some investigation, I found that the MIMWAL source package didn’t contain a .\src\SourceOutput folder. This explained why Visual Studio was showing the above warnings.

Based on my findings, I found two solutions that helped resolve the issue

Solution 1

Rebuild the Visual Studio Package again. On the second try, since the SourceOutput directory now exists, the files will be successfully copied.

Solution 2

Before rebuilding the MIMWAL package, create a subfolder called SourceOutput inside the src folder

My preference is for Solution 2 as it means that I won’t get any errors.

After successfully rebuilding the MIMWAL package, I ran sign.cmd and this time around – Success! I got the expected result.

VisualStudioOutputPane_Success

Signcmd_Successful

I hope this blog helps anyone else who might be having issues with compiling MIMWAL and running sign.cmd