“This demo uses the older MSOL cmdlets because they’re fast and familiar. In production or future-facing environments, use the Microsoft Graph / Entra modules instead.  When I get around to it I’ll post an update with those PoSH Modules…”

Windows Active Directory to Azure Active Directory generally works pretty well but there are times when the sync generates a new Azure AD user instead of linking to an existing account in Azure.  This generally happens when you’re onboarding a client environment to Azure where they already have a number of accounts in M365 that are in use, and now need to be directly linked to the on-premises Active Directory.  This is the difference between a “soft match” and a “hard match”:

  • Soft match = Azure tries to line up accounts by UPN / mail. Works most of the time.

  • Hard match = you set the ImmutableId to the objectGUID and force the link.

Typically I use the EmailAddress (Mail) attribute to cross-link the accounts.

Example:

Azure AD user:  Smiles J. McDuff

Azure AD email:  smiley@mydomain.com, sjmcduff@mydomain.onmicrosoft.com

In AD I then create the user –

AD User:   Smiles McDuff

SamAccountName:  sjmcduff

Set Email Address:  smiley@mydomain.com

When I do an Azure AD Connect Sync the new AD user should match to the Azure AD user and overwrite the user and attributes to that based in Active Directory.

Sometimes that doesn’t happen, such as making a typo with the email address, and instead of cross-linking the accounts between AD and AAD, a new user account is created in AAD.  Now things get tricky, because no matter how many times you delete the incorrect account in Azure AD, the next sync will just recreate it.

The solution is to capture the ObjectGUID attribute for the user in Active Directory and set that as the ImmutableID for the user in Azure.

Command:

Get-ADUser sjmcduff | select-object userPrincipalName, objectGuid

Result:

UserPrincipalName  :  sjmcduff@mywindowsdomain.com

objectGuid : b316d357-25fd-4912-9896-faf007a16289

Now convert that Guid to something we can use as an ImmutableID –

[Convert]::ToBase64String([guid]::New(“b316d357-25fd-4912-9896-faf007a16289”).ToByteArray())

Result:

V9MWs/0lEkmYlvrwB6FiiQ==

This is our new ImmutableID value for the Azure AD user account.

connect-msolservice

Get-MsolUser -UserPrincipalName “sjmcduff@mydomain.onmicrosoft.com” | select-object userPrincipalName, ImmutableId

Result:

UserPrincipalName : sjmcduff@mydomain.onmicrosoft.com
ImmutableId :                              [Confirm ImmutableID is blank -if not record it in your notes]

Command:

Set-MsolUser -UserPrincipalName “sjmcduff@mydomain.onmicrosoft.com” -ImmutableId “V9MWs/0lEkmYlvrwB6FiiQ==”

Comand:

Get-MsolUser -UserPrincipalName “sjmcduff@mydomain.onmicrosoft.com” | fl userPrincipalName,ImmutableId

Confirm ImmutableID matches

Now when you sync, the accounts should pair up properly.

What not to do:

Don’t do this:

  • Don’t change the sourceAnchor in AAD Connect after the fact.

  • Don’t set ImmutableId on the wrong cloud object — you can orphan the real mailbox.

  • Don’t try to “fix it” by renaming only — the join is identity-based, not name-based.

Privacy Preference Center