This week, I was contacted by an organization who were in the process of starting anew with Active Directory Domain Services (AD DS). The old Active Directory forest was too … old, basically. It showed signs of problems around attribute integrity, schema extension bloat and delegation defaults from the 00’s.
The challenge I assisted with, was a challenge around Azure AD Connect and object matching between the previously synchronized Azure AD tenant and the new Active Directory forest.
Object matching, the other way around
I wrote quite a lengthy blog post on soft-matching and hard-matching between Active Directory user objects and Azure AD objects. This blogpost details how to use the Azure AD module to set the mS-DS-ConsistencyGuid attribute as the ImmutableID attribute in Azure AD. However, this time, the process is the other way around.
There’s a couple of things you need to be aware of:
Set-AzureADUser –ImmutableId $Null doesn’t work anymore
For some reason, Microsoft botched the ability to clear the ImmutableID for Azure AD user objects. My experience is you can’t achieve this through Set-MsolUser, Set-AzureADUser, Azure AD Graph API or Microsoft Graph API reliably anymore.
Hard-matching before Soft-matching
When the ImmutableID is set for an Azure AD user object, Azure AD Connect will not perform soft-matching for that object. Instead, it expects to perform hard-matching, only. If hard-matching doesn’t work, for instance because the object in Active Directory doesn’t have the mS-DS-ConsistencyGuid attribute filled, soft-matching is not attempted.
Assumptions
Going forward, we acted on the following assumptions (that we double-checked):
- Objects from the previous Active Directory forest are not synchronized anymore to Azure AD and all objects show as cloud mastered objects in the Azure AD tenant.
- The objects in the new Active Directory Forest do not have values for their mS-DS-ConsistencyGuid attributes.
- Azure AD Connect is already deployed in the new Active Directory Forest and only has the users for the new Active Directory Forest in scope.
- The userPrincipalName attributes for the users in the Active Directory Forest match with the userPrincipalName attributes for the corresponding users in Azure AD.
Action plan
The action plan, therefore, is to fill the mS-DS-ConsistencyGuid attribute of a user object in Active Directory with the ImmutableID of the corresponding user object in Azure AD. Indeed, we need to match the user objects manually.
After we’ve matched the objects, we can set the value using the Set-ADUser Windows PowerShell cmdlet.
Script
To perform the actual changes on the mS-DS-ConsistencyGuid attribute for each user object in Active Directory, we use the following lines of Windows PowerShell:
# Change this value, or feed it from a For-Each loop
$upn = ‘joshaarbos@domain.tld’
# Sign into Azure AD with a privileged user
Connect-AzureAD
# Do not change anything below
Import-Module AzureAD
function ConvertFrom-ImutableIDToMsConsistencyGuid {
Param(
[String]$ImmutableID
)
[GUID][System.Convert]::FromBase64String($ImmutableID)
}
$ImmutableID = Get-AzureADUser -UserPrincipalName $upn | Select-Object -ExpandProperty ImmutableId
$MsDsConsistencyGuid = ConvertFrom-ImutableIDToMsConsistencyGuid -ImmutableID $ImmutableID
Set-ADUser –UserPrincipalName $upn -Replace @{'mS-DS-ConsistencyGuid' = [GUID]$MsDsConsistencyGuid}
What happens next…
Since Azure AD Connect does do soft-matching (as the ImmutableID attribute is present for the Azure AD object), Azure AD Connect gets that we perform hard-matching. Now, It will match the user objects in Azure AD to the corresponding user object in the new Active Directory forest.
As we took care of all the necessary passwords, group memberships, etc., we can resume business as usual.
Concluding
The above approach can be used to match previously synchronized user objects to new user objects from a new Active Directory Forest.
Of course, A better way is to use ADMT and include the mS-DS-ConsistencyGuid attribute in scope for migration and both Active Directory Forests in scope for the same Azure AD Connect installation. This minimizes the duration of the project, migrates all memberships and passwords (using PES) for you and makes it a much easier experience.
But … Some projects don’t start at the logical starting point.
need single quotes on last command?
Set-ADUser –UserPrincipalName '$upn' -Replace @{'mS-DS-ConsistencyGuid' = [GUID]$MsDsConsistencyGuid}
I am working on this exact thing as I am typing this. So what I am gleaning from this script is that the 'mS-DS-ConsistencyGuid' in the new On-Premise AD Environment needs to match the immutableID's in the tenant?
Assuming the answer is yes, would i then just rebuild the Azure AD Connect config to point to the new On-Premise AD Domain and it should just start syncing?
Yes, to both questions.
You'll need to install Azure AD Connect with the /SkipLDAPSearch parameter, and specify the mS-DS-ConsistencyGUID attribute as the source anchor attribute.
Hi Sander!
Your previous blog about hard/soft matching stated that Azure AD Connect no longer attempts to hard match or soft match Active Directory user accounts to Azure AD-based user objects with privileged roles, like the Global Administrator role.
Is this still true?
I created an Azure AD Global Admin account and an on-premise AD user (no sync yet).
The Azure AD user did not have an Immutable ID because never synced so I created one from the on-premise AD user.
Then I created for he on-premise user a matching MsDsConsistencyGuid
And finally I put the on-premise user in a OU to sync with Azure AD.
This all did work and my on-premise AD user took over the AzureAD Global admin user.
Also I deleted the on-premise user, the Azure AD user was put in the deleted users as expected, then created a new user on-premise and used the same MsDsConsistencyGuid on this new user.
Again after syncing this new user revived and took over the deleted Azure AD account.
https://twitter.com/rjong999/status/1451316231286374439
Set-MsolDirSyncFeature -Feature BlockCloudObjectTakeoverThroughHardMatch -Enable $True
I think this recently introduced setting would finally disable this functionality?
(no time to test this one :))
This should be enabled for new Azure AD tenants, as far as I know.