Wednesday, July 1, 2015

Did You Know: The Hidden Complexity of Intra-forest Migrations. #Office365

I’ve had numerous customers talk to me over the last several weeks about consolidating child domains into an empty root. In each of these cases the customer was looking to clean up old directories to prepare for a migration to Office 365. It is interesting to see how things come in waves. At any rate, I thought providing a quick primer on what happens during an intra-forest would be useful.

Each of these customers thought that the migration was dead simple and that they would be able to complete the migration in several weeks. After all, its not like the project will be dripping with complexity like migrating security principals cross-forest without a trust.

Ahh, the seemingly simple tasks that quickly take on a life of there own and become massive undertakings. I’ve had several of these types of projects around the house in my time and each one resulted in numerous unscheduled trips to the home improvement store.

Intra-forest migrations on the surface seem relatively simple, and they can be with the right planning. But with the wrong planning – these migrations can cause a lot of end user heartache.

How does this all work in an intra-forest scenario? Let’s review some of the basics here. For this discussion, I have a user account (adorsey) in a domain called with a NetBIOS name of NA. Now, let’s say that we need to flatten this child domain into the root domain called that has a NetBIOS name of CONTOSO.

If my account will be migrated to then my account needs a new unique SID from the root domain. Why?

A common misconception among customers that I talk to is that the user object like adorsey can simply ‘move’ from a child domain to the root. In practice, though, that is not technically what happens (even if using ADMT). When collapsing a subdomain into a root domain (intra-forest) a new user account is created for adorsey in the root.

The reason that a new user account has to be created for adorsey is that duplicate Object-SIDs cannot exist in the forest. This presents a challenge for intra-forest migrations because that means that you cannot easily prepopulate security principals without effectively deleting the original accounts.

Since a new user account is created in, a new SID must be generated for the user account and stored in the Object-SID property of the security principal. Each security principal can only have one Object-SID as this attribute is not a multi-value property.

So how can you see the Object-SID value of a user? Using the Active Directory Users & Computers tool is the easiest way to see what a users Object-SID is as shown below.

You can also use the dsquery command to show the Object-SID of a user. 

dsquery * -Filter "(samaccountname=adorsey)" -Attr objectSID

You may ask (like my customers) why can you not just inject the Object-SID from na\adorsey to contoso\adorsey?

Each SID that is stamped on new security principals is actually made up of several different items. First, the domain identifier portion of the SID is actually unique to the issuing domain. The first grouping of values contains information about the SID structure and domain membership.

The remaining values are arranged in a specific grouping almost like a telephone number. This grouping (or telephone number) contains the relative identifier (RID), which is handed out by domain controllers within the domain. Each domain controller is given a preset grouping of unique RIDs from a single domain controller that is configured with the RID Master FSMO role. This allows all domain controllers to have the ability to create new security principals and provide the RID when a new SID is created. This method also ensures duplicate RIDs are not handed out within the forest as well.

You can use the following command to see how many RIDs have been issued within your domain.

Dcdiag.exe /test:ridmanager /v

There are additional ways to use PowerShell to verify how many RID’s have been issued and what the highest number in the allocation pool is.

So if domain membership of a user object changes then the RID portion of the SID must also change to match the new domain. The domain identifier portion of a SID issued is unique to that domain as well. So the SID for contoso\adorsey has a different domain identifier then the original na\adorsey account. These are the rules of Active Directory. Period.

As you now see, you cannot just inject the Object-SID from na\adorsey to contoso\adorsey. So what happens with an intra-forest migration if Object-SID’s cannot be migrated?

Once the contoso\adorsey account has been created and stamped with a new Object-SID, the previous Object-SID value from the na\adorsey account is injected into the SID-History (sIDHistory) property of contoso\adorsey. The SID-History property can actually hold multiple entries and may already contain some values if you have migrated the account before!

So what is the best way to verify that previous Object-SID value from the na\adorsey account is injected into the SID-History (sIDHistory) property of contoso\adorsey? You can certainly use the Active Directory Users & Computers to see what values are stored in the sIDHistory attribute.

I like to use the dsquery command as it provides a nice way to copy or export the value. In the example below we see that the Object-SID value from the na\adorsey account is successfully injected into the SID-History (sIDHistory) property of contoso\adorsey after an intra-forest migration. 

dsquery * -Filter "(samaccountname=adorsey)" -Attr sIDHistory

To sum this up - each time a security principal moves to another domain, a new SID is generated. This SID is written to the Object-SID property and the old value is added to the list in SID-History. This of course happens only if sIDHistory is part of your directory synchronization project.

So when contoso\adorsey logs into the domain his Object-SID, values stored in sIDHistory, and the SIDs of each group he is a member makes up his access token. This token is provided whenever contoso\adorsey tries to access a file or share or any other NTFS-protected content.

Now I will point out that the field in which all these SIDs are stored within the access token is not an unlimited size. If the maximum number of SIDs stored in the access token is reached, the user may have problems logging into the network.

I’ve seen this situation of “token bloat” rear its ugly head within the scope of large-scale Exchange migration projects where RPC/HTTP is used as the client connectivity method. If you only have Windows 2012 or above domain controllers in your organization some of the token bloat issues have been relieved due to an increased default MaxTokenSize set. 
Regardless though, there is a maximum number of SIDs that can be stored in the access token for each user. 

So there you have it. I provided a basic primer for intra-forest migrations and explained how they can quickly become complex. The main point that I want to get across is that within an intra-forest migration ‘moving’ an account is actually a destructive process for the source account. That account is deleted and recreated in the target environment. This results in a limited window of opportunity to test and make sure everything works prior to migrating users. As with most projects, proper planning is required to achieve a successful migration.

1 comment:

  1. Thank you for this valuable information. Get your business to the next level in simple steps. We provides lowest price of erp Software for our clients cloud erp in Chennai | erp software solutions provider in chennai