As those of you that have seen me present know, I do a lot with STSADM. I find it to be an incredibly useful tool for large deployments, and pretty handy for smaller ones too. I've seen a few questions on how the migrateuser operation works, so I thought I'd write a little something up. Its purpose is to move permissions from one account to another. One scenario would be if a domain was being split up. You would want the new accounts to have the same permission as the old accounts. Another use would be accountname changes. If someone's account is renamed you don't want to have to grant them permission to all of the same resources. The usage for migrateuser is pretty simple. Let's take a look:
You just supply it with the old account and the new account and that's it. If you're not migrating from one domain to another you can tell it to ignore SID history as well. Some of migrateuser's behavior isn't obvious, so I thought I'd spell some of it out. Here is a crude flowchart (I didn't do well in art in grade school) that shows the logic migrateuser uses:
Ugly, I know. The main thing I want you to take away from this is that if domain\newuser has any permissions before you run migrateuser, they will be gone and replaced with the permissions domain\olduser had. They will not be combined. To demonstrate how this works I've created a site collection and given domain\newuser and domain\olduser permissions. Domain\newuser is in the Owners group while domain\olduser is simply in the Vistors group. You can see the information in SQL in this "before" picture:
Here are the two entries for domain\newuser and domain\olduser in the UserInfo table. You can see they each have their own tp_ID and their tp_Tokens are different. This token is where their permissions are stored. In the before picture they are different. I ran this command to migrate from domain\olduser to domain\newuser:
Pretty simple, nothing too it. STSADM is finished in a flash. Now let's refresh SQL and see what changes have been made:
There are a couple of things to note here. First, note tp_ID 9 has a tp_Login value of domain\newuser instead of domain\olduser in the previous screenshot. Essentially migrateuser just changed the value. Next you'll notice the tp_Token is the same as it was before. It was not changed to domain\newuser's nor were the two combined. Finally you'll see that domain\newuser's previous tp_ID, 8, is now marked as Deleted. That's the first step in the flowchart.
Besides removing all of domain\newuser's permissions, migrateuser has another "gotcha." Since it deletes domain\newuser's permissions before it maps them to domain\olduser's permissions (even if there are no domain\olduser permissions to map) there is a split second where it's possible that no one has permission. This is the case with Site Owners. If domain\newuser is the only Site Owner (meaning a secondary wasn't defined) then after migrateuser deletes it, the Site now has no Owner and cannot be administrated. I have not seen a way to recover from that. The site still renders, and users can still use it, but no administrative tasks can be done. In both cases that I've seen this I've had to recover the site from a backup. There may be a way to fix this in SQL, but I would recommendation against editing SQL by hand.
I hope this helps you understand the migrateuser operation a little better.