Search Results for: immutableid

ImmutableID – mS-DS-ConsistencyGuid – AADConnect – ADMT – Part 4 – Groups

In earlier posts I talked about ADMT and user accounts. Now a migration is never a full migration if groups are not migrated too. But how Azure AD Connect deals with users and groups is a bit different, certainly when custom anchors are being used. In this post we will be looking at how we can migrate groups from our SOURCE forest to a TARGET forest while maintaining the same link to the groups in Azure AD itself. First a review of anchors, attributes and metaverses:

In the picture above we see a quick representation of a user in Active Directory being synchronized to Azure AD. The ObjectGuid (copied into mS-DS-ConsistencyGuid) is copied into the sourceAnchor attribute of the user in the metaverse (database of Azure AD Connect) and that value is again copied into the cloudSourceAnchor attribute in Azure AD.

For additional linkage, the CloudAnchor attribute (created by Azure AD) is copied back to the metaverse as the CloudAnchor and then into the msDS-ExternalDirectoryObjectID in Active Directory for a user.

By having the same values on Active Directory and Azure AD – we can match users between the two directory services. When we perform an ADMT – and copy users from a source to a target, we just have to make sure these attributes remain the same – OR that we have a successful join of the now 2 source objects (2x Active Directory) in the metaverse.

A join makes sure there is only 1 representation of a user object in the metaverse of Azure AD Connect – and as such – only a single user in Azure AD.

In Azure AD Connect, you can configure the join rule based on an “anchor”. I call it the forest anchor as I don’t think there is a formal word for it.

Forest Anchor and groups

The forest anchor that you configure during the custom installation of Azure AD Connect however only applies to user objects. Not groups or devices. Now, devices do not really matter for this post – so I will focus on Groups only. And specifically security groups, as (AD) distribution groups are not synchronized to Azure AD at all.

By default, AAD Connect does have a join rule for Groups. The join rule is based solely on the msDS-ConsistencyGuid attribute, and thus you would think that in a standard ADMT migration for a group where the SOURCE attribute mS-DS-ConsistencyGuid is copied into the same target attribute would fix everything. However, this is where things go wrong: Where for users the ObjectGUID of a user in AD is copied into the mS-DS-ConsistencyGuid attribute field for that same user by Azure AD Connect, the same does not apply to groups. Meaning – by default the mS-DS-ConsistencyGuid of a group stays empty.

This means that prior to a migration we need to manually copy the source group OBJECTGUID into that group’s mS-DS-ConsistencyGuid field for mapping to happen. Once the mS-DS-ConsistencyGuid of the source group is set, then ADMT can copy this value to the target group during migration. Again, this is something ADMT or AADConnect will not do. Failing to manually copy this will result in multiple groups in Azure AD Connect – and thus Azure AD.

While each group might have the same members because of ADMT, their Object Id’s in Azure are different and thus permissions will not be applied to the new group (and to be more honest – it is confusing as you don’t know which group is from which AD).

So, we need to ensure we can join the groups and as said there are 2 options.

  1. Set the mS-DS-ConsistencyGuid on the source prior to the ADMT migration
    this will result in a matching attribute and a join rule will be activated. To help with this, I’ve added instructions on how to make sure this is set automatically in the source environment later in this post.
showing joined groups based on consistencyGuid match
  1. We create a custom rule that allows joining on something else than just msDS-ConsistencyGuid, but for example on the “custom” forest anchor we used for user objects. Given the complexity, this I will leave for now, but it is doable.

mS-DS-ConsistencyGuid for Groups

User objects in Active Directory will see their msDS-ConsistencyGuid being updated by Azure AD – is the attribute had a NULL value prior to synchronization. Effectively allowing Azure AD Connect to copy the ObjectGuid value into the msDS-ConsistencyGuid attribute. While this is not automated for groups, we could do exactly the same to prepare ourselves for an ADMT migration. In short, the instructions below will copy the user behavior to groups as well.

First, check if your Azure AD Connect configuration runs in Exchange Hybrid Mode – without this mode the group rules will not fire. – if you want to use a Pshell script.. check the last paragraph on this post..

  • In the synchronization rules, under Direction – select the Outbound direction and then click Add new rule
  • On the initial page:
    • give the rule a name (Out to AD – Group ImmutableId)
    • select SOURCE AD as the Connected System
    • Select Group as the Connected System Object Type
    • Select Group as the metaverse object type
    • Set Link type to Join
    • Set Precedence to +1 of the last rule (usually >200 is good)
  • Select transformations page and
    • Set flow type to Expression
    • Set target attribute to mS-DS-ConsistencyGuid
    • Paste the code below in the Source field
    • Leave Apply Once deselected
    • Set merge type to Update
  • Click Save

And this new rule will trigger the same attribute flow as for users, ensuring groups also have their mS-DS-ConsistencyGuid attribute filled with the ObjectGUID (or actually the cloudSourceAnchorBinary from the metaverse, but that is filled by the ObjectGUID). When performing ADMT, the migrated groups will be joined together.


You might be thinking this is all. However, if you had already imported the groups, the join rule will not kick-in. You will need to remove the groups from scope (effectively deleting them from the metaverse) and then reimport them to make the join work. This because of the fact that the sourceAnchor (based on ObjectGUID that was not copied) is still the immutable unique identifier for them in the metaverse and the created cloudAnchor in Azure AD is unique to each of the group objects as well.

Members of a group

While users are easily migrated, a group object is a bit more complex as it contains members. And members is an array on the group that is imported. Azure AD Connect will not append that array (the membership list) it will put in one source.

Similar to the ADMT migration of users and AAD Connect rule priorities, one AD is the winner for the attributes. This means in short – the first AD Domain/Forest added to Azure AD Connect is the winner for the “members” attribute for groups. In short, if the SOURCE AD was added first the members of the groups in SOURCE will always be replicated to Azure AD – and all members of the TARGET ADMT migrated group will be discarded.

If you would like to change this, and have the target as the primary, you’d need to change the order of the rules ensuring TARGET has a higher precedence than SOURCE.


It is a bit of a shame that someone forgot the rule to write-back the mS-DS-ConsistencyGuid for groups, certainly as it is by default being used in the join rules when multiple forests are connected. Now even when it is connected – be very aware that only the highest priority domain wins the members of the group and multiple groups are not merged. If you needed to have specific groups be the “winner” for the members you can create a separate inbound rule with the scope for those groups and the members attribute set, but that’s for another day … (or when requested)

PowerShell script

There are many scripts that can write the mS-DS-ConsistencyGuid for groups, but most of them require an input file with the groups. Something I would not like to do.. because it can contain typo’s etc. And obviously I want a script I can run over and over and over without it destroying stuff. So instead I wrote my own (in case you don’t want to use the method above). The script essentially scans a SearchDN for all groups without the ms-ds-consistencyGuid and only for those object copies those objectGuids into it. Furthermore, the script has a -confirm mode so you can actually scan first…

script to set ms-ds-ConsistencyGuid on groups that do not have this yet…

#script to set ms-ds-ConsistencyGuid on groups that do not have this yet... 

		HelpMessage="Type the DN of teh OU / forest to target.. for example: ou=production,dc=domain,dc=root,dc=local"
    	[Alias('Please provide the DN')]	
        HelpMessage='write $true to confirm writing of the ms-ds-ConsistencyGuid - else monitoring mode only - default is $false'
          	[Alias('Please use $true to confirm and write changes')]	
	    $Confirm = $false

Write-host "Targetting: $DN"
 $GroupsWithoutCon=Get-ADGroup  -Properties ms-ds-ConsistencyGuid -Filter * -SearchBase "$DN" | where {$_.'ms-ds-consistencyGuid' -eq $null}

 If ($Confirm) {Write-host "Confirm is set to $true - Writing changes" -ForegroundColor Yellow}
 else {Write-host "Confirm is set to $False - not writing - display only" -ForegroundColor Green}

 ForEach ($Group in $GroupsWithoutCon) {
    write-host ("setting ms-ds-consistencyGuid on " + $group.DistinguishedName)
    If ($confirm) {
        Set-AdGroup -identity $Group -Replace @{'mS-DS-ConsistencyGuid' = $group.ObjectGUID.guid}
        Set-AdGroup -identity $Group -Replace @{'mS-DS-ConsistencyGuid' = $group.ObjectGUID.guid} -WhatIf


et voila..

Tagged , , , ,

ImmutableID – mS-DS-ConsistencyGuid – AADConnect – ADMT – part 3b

In part 3a, we explained how ADFS can be used in cross-forest migrations to ensure all users (migrated or not) can still authenticate. In part 3B we will be looking at Pass-Through authentication and how it affects migrated/non-migrated users.

First of all, we need to make sure we have pass-through authentication agents deployed. In my environment I already have these agents deployed in the source (FORESTROOT), but not in the target domain. Obviously non-migrated users on the pass-through domain can authenticate.

So in order to first prove that the user is authenticating against the local domain (rather than using password sync), after the login, I checked the Security eventlog on the domain controller:

The event shows that the AzureADConnectAuthenticationAgentService.exe is requesting impersonation.

We can now also deploy additional agents on the target system, in my case I installed the agent on the target domain controller (but obviously you should follow official recommendations). The agent can be downloaded from the portal:

After the installation, I wanted to make sure that the newly deployed agent was able to authenticate my non-migrated users. Similar to how ADFS (see chapter 3a) setup was done. In order to force the new domain controller to authenticate my users, I stopped the agent on the FORESTROOT domain controller.

Now when we try to login to AAD with a non-migrated user, we will still see the following entry in the FORESTROOT domain controller, indicating a successful login. You will actually notice 2 entries in the security eventlog. The first being a 4768 and the second being 4769

These two events basically indicate a cross-forest authentication. What is important to note though is the User ID field in the 4768 event. The username is not represented as a UPN, but with the NETBIOS name. So let’s proceed to move this user to the new domain. Similar to the ADFS setup, I manually set the UPN for the user and ensured the ms-ds-consistencyGuid is the same on the source and migrated objects. The difference between pass-through and ADFS now becomes clear. Until the AADSync synchronizes the data, the user will continue to be authenticated in the source forest. This as the pass-through agents will use the NETBIOS information. This is visible when we look at the export details in the MIIS console for our export to AAD after we migrated the user:

As indicated in yellow, the netBiosName changed to the TARGET domain name. I manually edited the UPN of the user (in capitals for clarity).

In short, AAD will now upon entering a username in the login field, get the netBiosName and validate the user against that.

It is not that only the pass-through agents of the TARGET forest will pick-up the authentication, any agent can pick it up, but it will perform an authentication for NETBIOS\Username using the information known (netBiosName + onPremisesSamAccountName).

So as you can see, even pass-through authentication can be used for authentication to AAD in cross-forest migration scenarios!

Next up is the cross-forest authentications for regular services (like file servers..)

Tagged , , , ,

ImmutableID – mS-DS-ConsistencyGuid – AADConnect – ADMT – part 3a

To continue our coverage of ADMT and AAD, part three of the series. I know I promised 3 articles, but given the amount of data, I’ll split part 3 (authentication) in a few more posts..

We have 1 AAD and 2 AD’s; FORESTOOT.local as the source and TARGET.local is still the target AD forest. There is a two-way forest trust between the two forests Forestroot.local is still based on Windows 2016, TARGET is still based on 2012R2. And we continue to have our members server in the target.local domain that functions as the ADMT and AAD Connect server.

This post will dive further into authentication and access as users are migrated from the source to the target.

When looking at ADMT and migrations in combination with AAD, we have two types of authentication that we need to take care of. Firstly, the cross-forest authentication to member servers and resources, and secondly the authentication on AAD itself. In our earlier migrations we ensured that we would authenticate against the AAD itself by synchronizing the passwords and using managed domains, but there are 3 types of authentication possible with AAD, which we will start with.

  • Federated Authentication
  • Pass-through Authentication
  • AAD Based Authentication

With federated authentication, a user that tries to login to AAD will be redirected to a federation server (usually ADFS) and needs to perform an authentication there. Upon successful authentication, a token is provided that the user then provides to AAD to indicate a successful authentication and providing identity proof. It is up to the federation server to authenticate the user (in any form) and provide the token. Basically, AAD doesn’t care how you authenticated, as long as the token the user provides is valid.

In our cross-forest authentication scenario, this comes down to essentially the same as accessing cross forest resources. In our setup, we did not add any UPN suffixes to the TARGET domain nor did we add them to the routing table (as having conflicting UPN suffixes would not be supported). During our user migration (using ADMT) the UPN automatically got updated on the new user object in the TARGET domain to represent target.local.

It is possible to keep the UPN in a scripted ADMT migration, but in our example we will just update the UPN manually for the migrated objects. ( So, after the update, we end-up with two user objects, representing the same user that both have the same UPN.

Given our users need to login with their email (UPN), means that if our federated user wanted to authenticate against the ADFS server hosted in, the server would validate the UPN only at its own forest. This as the UPN routing table in the forest trust has the suffix “” pointing to the forestroot.local forest (this as the UPN suffix was not added to TARGET.local, nor was it added in the UPN suffix routing table on the trust).

Only if users where to change their login name to TARGET\username would the forest trust be applicable. So in order to avoid this situation, we can actually move the ADFS services to the target domain. This way, non-migrated users authenticating with their UPN, would be authenticated against the FORESTROOT.local forest, given their UPN matches the UPN routing suffix in the forest trust. But (migrated) users, who have their UPN set locally (in the target.local forest) can be authenticated by the Target.local domain controllers.

In my demo environment, I’ve setup another federation server in the target.local forest and gave it a new public URL. I’ve also manually set the UPN for my (migrated) user in the target domain to match the UPN of that object in the forestroot.local domain (matching the user’s e-mail address), as well as ensured that the ms-ds-ConsistencyGuid was equal for both objects.

The thing we must do now, is switch the federation service manually on Azure AD for our specific domain. Switching means that all users trying to authenticate with to Azure AD will be redirected to the target.local ADFS server. Given the forest trust and UPN routing suffix on that trust, users trying to authenticate to the ADFS server and that do not exist in the local domain(!) will be validated over the trust.

(Note that in this case, the ADFS can only look-up UPN’s in its own domain, not forest. Given the UPN was not added on forest level, only domain wide authentication can be performed. Adding to the target forest would result in the UPN suffix routing table disabling the routing for the suffix and therefore render this solution unusable).

In order to change the AAD configuration, I loaded up PowerShell and logged into MSOL and changed the domain federation configuration:

Update-MsolFederatedDomain -DomainName

Next up, is changing the ADFS configuration. By default it will use the objectGUID for validation (see my other entries) and as such, we need to configure ADFS to use the ms-ds-consistencyGuid. You can obviously also have AAD Connect configure this for you. I followed this article.

Now after this is all set, we are ready to go. You can try to login to Offic365 and the main Microsoft AAD page will redirect now to the new ADFS server. There you can login using the migrated account (in the form or TARGET\user, or or you can actually also login still using the original account using FORESTROOT\user. Non-Migrated ( users will be authenticated based on their UPN over the forest trust.

In short, this article showed you the inner workings of the O365 login. It uses a combination of UPN + ms-ds-ConsistencyGuid which can exist on more than one domain. Using some trickery we can actually move all our users to the new forest while still allowing non-migrated users access to a new ADFS farm to login. Migrated users can continue to use their existing UPN while logging on to the new forest, even though that new forest does not have their UPN suffix officially registered.

I promised I would make three blog post entries.. but will continue in part 3b with the PassThrough Authentication.

Tagged , , , ,

ImmutableID – mS-DS-ConsistencyGuid – AADConnect – ADMT – part 2

In our previous post we explored the backend of Azure AD Connect and what happens in multi-forest scenarios. In this post we will be looking into the ADMT migration and the effects on the cloud accounts.

The FORESTROOT domain has a user ( which has been assigned a full E5 license to Office 365. The user is able to login and has a mailbox as well as some other things configured.

We continue to build on our previous installation, but in order to support the migration, we will be switching the Azure AD Connect instance to the stand-by instance and disabling the Azure AD Connect on the FORESTROOT domain.

Ensuring all users are there

But prior to doing this, let’s make sure the details will be the same when switching over. On the FORESTROOT AADConnect server, open the MIISClient (“C:\Program Files\Microsoft Azure AD Sync\UIShell\miisclient.exe”) and select the metaverse tab and search for the user:

Now most-importantly is the sourceAnchor. As indicated, its f8ys/….

On the TARGET Azure AD Connect server, open the MIIS client, and if not already available in the MetaVerse, run an import and sync job.

If you notice that the user is not in the metaverse, then this is because you left the mail attribute field empty. As this is the unique identifier for the users in each forest in our scenario, you need to ensure all users have the “cross-forest anchor” attribute (mail) populated.

When opening the properties of the user, you should see the same sourceAnchor:

Prior to disabling the FORESTROOT or SOURCE AADConnect, make sure the TARGET AADConnect can see and read all existing objects.

Switching Azure AD Connect’s

Open Azure AD Connect on FORESTROOT, and click configure on the main page. Then select Configure staging modeOpen Azure AD Connect on FORESTROOT, and click configure on the main page. Then select Configure staging mode

Login to the tenant, and then select enable staging mode and de-select the start synchronization process when the configuration completes. This basically disables the AAD on the FORESTROOT.

Now we can do the same on the TARGET Azure AD Connect, but here we want to disable the staging mode and there remove the checkbox. On this system we can initiate the sync process.

ADMT – Migrating a user

Let’s suppose we perform a standard ADMT without setting any option for the migration. To ensure the Azure AD Connect does not run (as I want to have control over it), I open up Azure AD Connect (from the Desktop).

I start ADMT with my special ADMT user and perform the migration of

Given I still want to use the source account, I leave it enabled, but will also migrate the user’s SID (for other purposes outside the scope of this post).

As you can see, I did not exclude any attribute from the migration.

After the migration we take a look at what would happen with the account in Azure AD, we do this by opening the MIIS Client and performing an import on TARGET and FORESTROOT followed by a synchronization on FORESTROOT and TARGET. You will notice nothing has changed. The object in Azure AD Connect is still the FORESTROOT object and the TARGET object is ignored. Why? Let’s checkout the migrated object in TARGET in the ADUC console:

As you can see, the default ADMT migration does not include the mail attribute. Which is strange, given we did not exclude any attribute by default.

By default, ADMT has a set of attributes it will migrate. This set does not include the “Exchange” attributes such as proxy-addresses and the mail field. ( In order to enable the migration of these attributes we need to run a script:

Perform the following:

  • Create a directory called C:\Scripts
  • Open an Administrative DOS prompt
  • Notepad c:\scripts\ADMT.vbs
  • Create a new file and fill it with
Set o = CreateObject("ADMT.Migration")
WScript.Echo o.SystemPropertiesToExclude
  • On the prompt, go to C:\Windows\SysWow64
  • Execute cscript c:\scripts\admt.vbs

The output will show all the excluded properties of the system, and as you will see, it contains the mail, proxyaddresses, and a whole lot more. The output will show all the excluded properties of the system, and as you will see, it contains the mail, proxyaddresses, and a whole lot more.

Next what we need to do is ensure we include the properties that we want in our migrations. For this, execute the following on the same command prompt

  • Copy the attribute list as shown above
  • Notepad c:\scripts\newADMT.vbs
  • Create a new file
  • Paste the following information:
Set o = CreateObject("ADMT.Migration")
o.SystemPropertiesToExclude = "msDS-PSOApplied,msDS-HostS………"
  • Where the SystemPropertiesToExclude is the list you actually want to exclude
    I removed, mail and proxyAddresses, DepartmentNumber, EmployeeNumber, employeeType, homePostalAddress and some other properties..
  • Run c:\windows\syswow64\cscript.exe c:\scripts\newADMT.vbs
  • Run the first script to validate the inclusion of the attributes

Now we can re-do the ADMT migration by deleting the object in TARGET, or update the ADMT migration by running it again and allowing conflicts.

I just deleted the object and re-did the entire ADMT. Now in ADUC we actually see that the mail attribute was copied too. What is the effect on our object in AAD Connect, now that the mail field was populated too?

You will notice that the Contributing MA has been switched to TARGET.local for our user. But as you can see the cloud anchor is still set to f8ys/…. Which means, this user’s mailbox, login and all is still safe.

Now we can close the still opened Azure AD Connect configuration page that was pausing our synchronization and execute a delta sync through powershell

Start-ADSyncCycle -PolicyType Delta


How come we don’t have a problem with this user compared to our previous post where a change in the sourceAnchor was detected?

When Azure AD Connect synchronizes users, it will take the ObjectGUID from a user and copy it into the ms-DS-ConsistencyGuid attribute field (or any other field you have specified as the immutableID field and that is capable of hosting the same data type). When performing an inter-forest migration using ADMT, the process actually copies the ms-DS-ConsistencyGuid attribute to the migrated object.

Given the uniqueness of ObjectGuid for every forest/domain, you cannot copy the ObjectGuid from source to target. That is why the migrated user will have a unique ObjectGuid. If ms-DS-ConsistencyGuid was not populated yet (because it was a brand new user), or another attribute that is excluded from ADMT is used as the ImmutableID, the new Azure AD Connect will create a new ImmutableID. In our example, the migrated user Smith, has an ObjectID of :

While his ms-DS-ConsistencyGuid (copied from FORESTROOT) looks like:

In the next blog-post we will see what happened to the authentication of the migrated user. Cause as some readers may have noticed, we still do not have implemented the UPN on the TARGET domain…….

Tagged , , ,

ImmutableID – mS-DS-ConsistencyGuid – AADConnect – ADMT – new series

My posts on the ImmutableID seem to continue attraction from all over the world, and thus, let’s continue the fun. In a new series of posts we will be looking at the influence of the ImmutableID and Cross-Forest Anchor (name given by me, not sure if it is the actual name for it) in an ADMT cross-forest migration scenario. Or in other words, how can we make sure to keep the AAD (/Office 365) user the same, while migrating the backend user between forests.

In the first part we will go over the tools and show how certain things work in the back-end by importing duplicate users.

Infrastructure setup

First the setup, I have 1 AAD and 2 AD’s; FORESTOOT.local is the source and TARGET.local is the target AD forest. While Forestroot.local is based on Windows 2016, TARGET is based on 2012R2, just for the sake of showing this will work also on older AD implementations.

In the target.local domain I have a member server that will function as the ADMT and AAD Connect server.

First things first, let’s install ADMT:

  • On Target.local
    • Create a new user “admt-admin”
    • Add the user to Domain Admins
    • Create the Forest trust to Forestroot.local can be one way or two way)
  • On the PDC of Forestroot.local:
    • Create a local domain security group called FORESTROOT$$$
    • Create the Registry Entry: TcpClientSupport = 1 (DWORD) under HKLM/CCS/Control/LSA
    • Enable Account Management Audit (success / failure) in the Default Domain Controller Policy
    • Add admt-admin to the Built-in\Administrators group

Login to the ADMT member server as admt-admin and install ADMT

Secondly, let’s install AAD Connect:

              I already have AAD Connect on my Forestroot domain controller. But given we are now going to use 2 forests, we have to be able to select our immutableID and cross-forest anchor. Furthermore, usually these migrations end-up in removing the source forest all together, so we’d need to install AAD Connect again anyway.

The idea here is to install the 2nd AAD Connect in Staging mode only. This allows us to review the configuration, the exported objects and if indeed our ruleset and settings replace the backend accounts on our AAD users, rather than creating new ones, or removing them! (which can happen in a faulty config). So on the ADMT server, install AAD Connect and choose the custom installation option, add both forests to the configuration:

Figure 1: AAD Connect Installation - two forests

On the UPN screen, select Continue without adding UPN suffixes to verified domains. This is because we don’t want to interrupt the UPN routing between the two domains as part of the forest trust. When we migrate the users, we will also migrate their UPN itself.

Figure 2: AAD Connect - UPN Configuration

Next is the screen for uniquely identifying our users, in this screen there are two settings that need to be configured.

First is the what I call Cross-Forest Anchor. This attribute identifies a single user having two accounts (one in each forest). The link between the two can be based on any attribute, but usually it is the mail attribute field, or in the case of an Exchange ResourceForest, it is the ObjectSID and the msExchangeMasterAccountSID (the 2nd option). It is also possible that the sAMAcountName is the same (but not usually).

I’ve configured the system to use PassThrough Authentication. This is to make things a bit more complex, the easiest would be to use Password Sync and the hardest would be to use Federation (in case the UPN of the user does not change), but we will cover the authentication part later.

Figure 3: AAD Connect - Identifying users

If two of “the same” users are found that don’t have a matching attribute, two things can happen. The users get removed from the metaverse (as we will see later), or two accounts are created in AAD.

The second option is the ImmutableID. In the later versions of AAD Connect, when choosing Let Azure manage the source anchor, the ObjectGUID of the user is automatically copied into the ms-DS-ConsistencyGuid attribute and that is used for the anchor. But you can also specify your own anchor.

In our previous posts, this anchor was used to match two user objects to a single AAD user in the metaverse. But with the later versions, the Cross-Forest Anchor does this for us automatically. As I want to use the default ms-DS-ConsistencyGuid anyway, I left it to the default setting. I finished the installation of AAD Connect, but making sure to select Staging mode.

The initial look

We will start by creating duplicate accounts, and matching them on email attribute.

I created two accounts:

FORESTROOT\duplicateUser       e-mail:
TARGET\targetduplicate              e-mail:

Now we open the MIISClient, so we can see under the hood what’s actually going on. Go to C:\Program Files\Microsoft Azure AD Sync\UIShell and open MIISClient.exe

Under the connectors tab, we see 3 connectors, one to the AAD tenant, and two for AD (Forestroot / Target)

The way MIIS (AAD Connect is based on it), works, is that there is a metaverse. A central database with all our users, groups and other objects. Each Connector also has a connector space. This space is a 1:1 match to the connected system (in this example AD). It keeps track of all the imported and ready to be exported objects. The system works as follows: An Import reads the source (AD) and puts all the objects in the Connector Space. A Synchronization moves the objects into the metaverse, keeping track of all the rules that apply to this connector (for example, joins, renames, etc). Once a change in the metaverse for an object is detected it is placed in the connector space ready for export. And on an export job, it actually pushes the changes to the connected system.

Right-click the AD connectors, and select Full Import, once completed, right click TARGET and select Full Synchronization. This ensures that our initial object is in the metaverse. On the FORESTROOT connector, we are going to perform some investigations (to learn what happens). Right click the connector and select Search Connector Space. Leave the Scope to Sub-Tree and click search.

The list shown is the list of users in the connector space only. This is the 1:1 copy of the AD information, but it’s not yet in the metaverse itself. In the list you will find our Duplicate User. Click it and select properties (or double click).

The pop-up shows you the user and the changes (add to the system in this case) and the attributes that have been read from the user. Given this user does not have a lot of attributes set, there is only a limited set imported.

Before actually moving/importing the user in the metaverse, we can run a simulation. This can be done by clicking Preview..

There are two options available, delta and full. In this case it doesn’t really matter which one you choose, so we will go ahead with the Full Synchronization – Click Generate Preview

The preview generates what would happen to this particular object if a full sync would be executed.

It shows the Source Object Details similar to the ones shown before, but in our case more importantly, there is a Join and Projection tab available too. This one shows us that this object would be matched (joined) to an existing object in the metaverse (remember, we already imported the user from the TARGET AD and that was already synchronized to the MetaVerse).

Go back to the Start Preview tab, and click Commit (a warning will show indicating a new preview will be re-generated). By issuing the commit, we now have successfully copied the object into the metaverse and now should have a single object with 3 connectors in the metaverse. To check, close all the pop-up windows and select metaverse, and then search:

Find the user and double click to get its properties.

As you can see, the user was updated with the TARGET AD information. Remember, the FORESTROOT sAMAccount name was “duplicate user”.

So an important lesson now, the order of the rules in the AAD Sync Engine determines which AD is authoritative for objects and attributes. Given we want to move to the TARGET domain, I added that one first to AAD Connect, and then added the source domain.

If on the window we select Connectors, you can actually see the three connectors this object is connected to:

Now let’s take a look at where this join is configured in the ruleset. For this, we open the rule editor, let’s take a look at the configuration: Go to C:\Program Files\Microsoft Azure AD Sync\UIShell and open SyncRulesEditor:

The SyncRulesEditor shows you all the rules that are applicable to AAD Connect. In MIIS you had to programmatically set the rules, but in AAD Connect it’s a bit easier. As you can see, the first two rules are the User Join rules. Click the first one and select Edit (a pop-up will show, click NO). Select Join Rules and you will see:

This means that if the source attribute (from TARGET AD: mail) is equal to an existing object in the metaverse with attribute mail, these objects are Joined together.

As you can see, the 2nd rule has the same settings as this applies to FORESTROOT. This means that when importing objects, they are not matched on AD-to-AD and then pushed into the metaverse, but they are AD->Metaverse and AD2->Metaverse.

Now let’s see what happens if we have a single object in FORESTROOT and after a while a new object is created in TARGET with the same mail attribute.

First, Jon Doe in FORESTROOT. It is added to the metaverse with a sourceAnchor of pPkD….. during a normal synchronization. We then created Jane Doe in TARGET and imported it as well. In this case I ran just the delta import from TARGET to show what is happening:

Next click the AAD Connector, select search Connector Space and set the scope to Pending Export. Click search. When you only have a few objects just click through the users to find the right one (in very large organizations, check the object in the MetaVerse first, grab the GUID for the right connector on the connectors tab, and search for that one in the pending export window).

The image above shows the export attributes (to AAD) for JaneDoe (which used to be Jon Doe), with a new sourceAnchor (4uYO….), but the two accounts are merged in the metaverse:

The change of the sourceAnchor attribute does not have to be that bad, but we will see in a later chapter how to avoid this from happening.


When connecting AAD Connect to two or more forests, it will ask you if objects are unique within each forest, or if in the ruleset a join rule must be created. If you enable this option (which you should if you are doing AD Migrations) you should be aware that unwanted matches can occur. If running in complex environments, choose your attribute wisely. We’ve also seen that the first forest added to the configuration is leading. This means that the existing objects might be changed due to the objects (and their different values) in the first forest.

Tagged , , , , ,

ImmutableID – mS-DS-ConsistencyGuid – ADConnect – final part

One of the most looked at topics on this blogpost is the ImmutableID series for Azure AD Connect and AADSync. And I wanted to give an update to this, given the latest versions of Azure AD Connect seemed to have adopted the idea to use the ms-ds-ConsistencyGuid (or any other value) to replace the ImmutableID used for synchronization. Don’t worry, please keep reading the other posts, as they clearly explain the how behind the idea of using the alternative ImmutableID.. and this post is just to tell you.. Microsoft has made the implementation a lot easier!

Read more

Tagged , , , ,

ImmutableID – mS-DS-ConsistencyGuid – ADConnect

The good thing about new software is that bugs and ‘features’ are removed.. the bad is that sometimes what ever you have blogged about makes either no sense, or even worse it only applies half to it from that point on.

So as AADSync was replaced by AD Connect, I got emails about the configuration of the mD-DS-ConsistencyGuid configuration in AD Connect not correctly working anymore. So, in order to relieve me from those email (you can still send them no worries) but more to make everyone aware of how this works in AD Connect (tested version; part two of the mS-DS-ConsistencyGuid as the immutable ID.

[update 21-Aug-2017: The latest version of Azure AD Connect have the functionality built-in to select the ImmutableID. There is no need to hack the rules manually anymore.. read more about it at:]

Read more

Tagged , , , ,

ImmutableID – mS-DS-ConsistencyGuid – AADSync

Paul Williams talked in his blog about using another attribute from on-premises Ad’s to act as the ImmutableID for Azure Active Directory (

While making a very detailed blog entry on why and which attribute to choose, there wasn’t a guide on how to make this work in AADSync.

[update 21-Aug-2017: The latest version of Azure AD Connect have the functionality built-in to select the ImmutableID. There is no need to hack the rules manually anymore.. read more about it at:]

So a recent project got me thinking about this. In this particular scenario there is already a forest (1 domain) using DirSync to replicate their users to AAD, and the requirement is to prepare for an AD migration, while also adding other users to the same AAD tenant. As usual, user objects might be duplicate between the two forests and we want to use the mS-DS-ConsistencyGuid attribute to be the immutableID.


Read more

Tagged , , , , ,