Recently, I was doing some user migration work in a SharePoint 2010 environment and I ran into something pretty interesting. The important details of this work are as follows:
So far, so good. Had this been all one domain, two separate farms, users would be able to begin testing content and validating the data migration was successful. Here’s where this migration gains a little in complexity.
Even at this point, we’re still ok. We’re all SharePoint professionals who have dealt with domain Migrations before, or an account that has been deleted and recreated – so this is nothing new. So now we have two viable options to get out of this mess.
With our 3 viable options outlined above, (#4 not being viable), I chose to use the 2nd option and wrote a PowerShell script to do the work for me. This worked great until the Move-SPUser Cmdlet was used against the Object Cache accounts. Everybody remembers those accounts right? In case that doesn’t ring a bell, maybe “Portal Super User” and “Portal Super Reader” accounts will sound more familiar. As soon as we got past executing the Move-SPUser Cmdlet against these two accounts, even valid migrated accounts which worked earlier in the migration process received the SharePoint access denied page. Even the site collection administrator account was denied access. Even accounts granted full control via web application policies was denied access. For anybody who has seen this issue before, this is immediately identifiable as a web application which is missing entries for the Object Cache accounts. Using PowerShell, we can verify that the Portal Super User and the Portal Super Reader properties for the web application do exist and have the correct account configured. What was peculiar is that previous policies for web application had been removed as a result of running the PowerShell script.
Further testing indicates that whenever you run Move-SPUser against a user account, any web application policies defined for that account are removed from all web applications. The exception in this case appears to be for the “Search Crawling Account”. Possibly any policy where the user display name does not match the display name for the user in Active Directory – but that requires further testing. What happened in my case is that once the Move-SPUser Cmdlet was executed against the Object Cache accounts, the policies for the web applications granting full read and full control to these accounts was removed. Further to this, the full read policy granted to NT Authority\Local Service was also removed.
The fix for this issue was actually pretty simple. As part of the script, I initially record the Object Cache accounts to a variable. At the end of the script, once all user accounts have been migrated using the Move-SPUser Cmdlet, I set the Object Cache accounts to their former values (this step is optional, because they don’t actually get erased) and configure web application policies to grant the appropriate permission levels to both of these accounts, as well as the NT Authority\Local Service account. I will post the set of scripts I used for this once they are sanitized (probably a day or two).
The lesson from this blog is: Be careful when you use the Move-SPUser Cmdlet. It can and will erase any web application policies for any user accounts against which this Cmdlet is run.
Now that we all know about this, it’s pretty simple to plan for this and to work around this issue.
Go ahead and test this out for yourself – I’d be very happy to hear if this does not reproduce in your environment, as it’s easily reproducible in 100% of the environments in which I’ve tested.