SharePoint, MySites and AD domain migrations. How to make it happen smoothly

I was recently involved in an AD domain migration for a client that was running SP2013 onPremise. This client was utilizing SharePoint as a company portal, as a collaboration portal (teams sites, projects sites etc) and for its social features (mysites, newsfeeds etc).

We had some unique requirements and I couldn't really find any good guidance for doing domain migrations while ensuring that SharePoint isn't ensuring that mySites don't get deleted....hence this post.

The SharePoint environment was not a vanilla install. Here were some of the customizations (if you want to call them that):

  • It was configured to use ADFS SAML claims for authentication;
  • It had a custom claims provider that drove the people picker. The claims provider picked claims from the UPA;
  • A BDC connector augmented profiles in the UPA with data from the customer's Peoplesoft repository.

As part of the domain migration, we had some unique requirements to deal with. One example was that the source accounts needed to remain enabled as all the applications had not been updated to work with the new domain.

This presented a unique challenge in that, migrated users could log in as their old IDs (and you know they will) and cause new SharePoint profiles to be created. They would also quickly find out they couldn't access sites using that old ID, which would lead to helpdesk calls etc. Just messy, messy, messy.

So here's how we did it. I'll explain the rationale behind each step where necessary. Feel free to pick and choose to suit your environment.

Steps to perform before the migration starts:

1. If you have your QA or Dev SharePoint farms populated with user profile data similar to Production, disable outbound email flow in those QA or Dev SharePoint farms.

  • You typically won't care about any mysites in those environment, disabling email will prevent managers from getting mySite deletion notifications.

2. Before the AD migrations start, create a new sync connection in SharePoint for the new domain. The new domain shouldn't have any users yet. So nothing to worry about yet.

3. Check what time the UPA runs incremental sync every night and also when the MySite deletion timer job runs. Both usually start at 1am.

  • This is important because you'll want to make sure these next few steps happen (and finish) before 1am. Alternatively, you may choose to disable these processes.

4. Modify the AD sync connections through FIM to prevent duplicated groups.

  • $TODO

5. Work with your domain migration team to ensure that the processes for migrating a user's account happen before 1am.

6. If the migrated accounts will be re-enabled, have them plan on marking some attribute (we used msExchExtensionAttribute44) on the old account (ie migratedToNewDomain) so you can filter these accounts out later.

7. If step 6 applies to you, modify the AD MA for the old domain and add a new "Connector Filter" on the User object type that reads msExchExtensionAttribute44 Equals MigratedToNewDomain.

  • This step requires you to make the edit in the FIM client. Alternatively, you could do it in Central Admin. Just be sure to reverse the operator...central Admin expresses logic backwards.
  • At any rate, the reason for making this change is to cause FIM to filter out the account that has just been migrated.

8. If step 6 applies to you and you use ADFS SAML claims, have your AD migration team also add the old user account to a group in the old domain ie UsersThatHaveBeenMigrated.

  • By having the old user accounts added to a group as they are migrated, you can tell ADFS to deny any users that are members of that group from logging into SharePoint.
  • This will prevent users from creating new non-synchronized profiles in the UPA and creating cleanup headaches for the SharePoint Admins
  • In ADFS, go to each relying party you have for SharePoint. Edit the claim rules and on the Issuance Authorization Rules, add a "Permit or Deny Users Based on an incoming claim" rule
  • In the rule, choose "group SID", specify the group from the old domain and select Deny.

6. Ensure that user's don't access SharePoint during the migration. This should be obvious, but it's worth mentioning.

 

Steps to perform when the migration starts:

 

1. Have the AD migration team run the following for each migrated user. At this stage, ADMT will typically have disabled the old account and created a new user in the new domain. In our case, we were re-enabling the account to allow them to work with unported applications.

  • stsadm -o migrateuser -oldlogin "i:0e.t|your custom claims provider|user@olddomain.net" -newlogin "i:0e.t|your custom claims provider|user@newdomain.com" –ignoresidhistory
  • Don't worry that the new account has not been imported into the UPA yet. You don't want it in the UPA yet.
  • This command works better than move-spuser because move-spuser requires you to bind to each spweb that a user might have permissions to. Not efficient.
  • This command will change the account name on the profile (which still belongs to the old user) in the UPA to the new account name.
  • Then it will modify the permissions on each site...essentially mapping the old account to the new account. This is what will allow the users to access content they previously had access to.
  • The command should be run as the farm account.
  • Run this step to before any UPA sync steps have run. Ignore this at your own peril.
  • After running the command, the user's permissions has mapped over to the new account. And the profile in the UPA has a new account name mapped to the new domain BUT the profile is still bound to the old user (the SPS-DistinguishedName still points to the old user account). Again don't worry...keep reading.

2. Next, in the FIM client, manually kick off a delta import and delta sync on the old domain's MA.

  • This will detect that the old user account has been disabled OR filtered out (if it was re-enabled)
  • It will queue up a delete for the old profile. Sounds scary...but don't panic.

3. Next, in the FIM client, manually kick off a delta import and delta sync on the new domain's MA

  • This will detect the new user account in the new domain
  • This will queue up an Add of a new user in SharePoint.

4. Next run an Export and delta Import on MOSS MA again through the FIM client.

  • This will send a delete to SharePoint for the old user profile.
  • This delete will mark the profile in the UPA as deleted. Don't panic
  • Then the queued up ADD will re-animate that profile. What enables this to happen is the stsadm migrateuser step which changed the account name on the profile to the new user's account name. When FIM tries to add the new user, it finds an existing profile (that's marked for deletion) and re-animates it.

5. Next, run a delta import and delta sync on any BDC MA, followed by a Export and delta Import on MOSS MA.

  • This only applies if you have a BDC MA that brings in data from an HR system 

 

That pretty much sums it up. At this point, users can be allowed to log in and they should find their profile data still intact and access to their existing sites still intact as well.

Issue we ran into:

1. Links to followed documents may not work.

  • We changed UPNs as part of the domain migration...ie we went from using a123456@olddomain.net to joe.blow@newdomain.com.
  • As you know, MySites are built using the account name...so Joe's mySite prior to the migration was something like: https://my/personal/a123456
  • At some point, the UPA will change the mySite path to https://my/personal/joe.blow
  • Now imagine that a user was following a document in Joe's mysite prior to Joe being migrated. In other words, that user is following https://my/personal/a123456/somedocument.docx
  • Well, that reference is not updated when Joe's mySite is refreshed to reflect his new account name.

2. Sitefeed and newsfeed references to user accounts break.

  • It appears that newsfeed content stored in the Microfeed lists in mySites and TeamSites have static/absolute references to user accounts. So after the migration, you'll notice that feeds no longer show friendly names but instead show the much uglier claims encoding reference ("i:0e.t|your custom claims provider|user@olddomain.net").
  • The only way to fix I know of is to programmatically search for and modify each reference. Not fun at all. We made a business decision to deal with it.