Hi folks, Ned here again. Frequently someone asks me how to make USMT 4.0 migrate only recently used domain user profiles. This might sound like a simple request for a USMT veteran, but there are some subtleties caused by processing rules and behaviors. Today I go through how this works, talk about pitfalls, and ultimately show how to solve the issue. Forearmed, you can solve quite a few more migration scenarios once you understand the rules and technique.
The goal and initial results
The plan here was to migrate only Cohowinery.com domain user profiles that had been accessed in the past three months, while skipping all local user profiles. This test computer had a variety of local and domain profiles, some of them very stale:
The USMT syntax used was similar to this:
Scanstate.exe c:\store /uel:90 /ui:cohowinery:\* /i:migdocs.xml /i:migapp.xml /c /o
So far so good. Then they restored the data:
Loadstate c:\store /uel:90 /ui:cohowinery:\* /i:migdocs.xml /i:migapp.xml /c
Which failed and returned to the console:
Starting the migration process
Processing the settings store
Selecting migration units
Unable to create a local account because /lac was not specified
See the log file for more information.
LoadState return code: 14
Looking in the loadstate.log they saw:
The account 7-x64-rtm-01\admin is chosen for migration, but the target does not have account 7-X64-RTM-01\admin. See documentation on /lac, /lae, /ui, /ue and /uel options.
Unable to create a local account because /lac was not specified[gle=0x00000091]
What the? The “admin” user is a local account. Why was that migrated?
So they went back and examined the scanstate console and noticed something else:
Huh. All the domain users were migrating, even though the BShirley and SDavis had not logged on in more than two years. They could enable /LAC to stop the loadstate failure but that wouldn’t accomplish the goals.
Understanding what happened
USMT has complex rules around profile precedence and the /UI, /UEL, and /UE command-line switches. Despite the best efforts of our talented TechNet writer Susan, the syntax is inherently nutty. Let’s get the rules straight here first:
- /UI (User Include) always migrates a profile, regardless of /UE or /UEL. This looks simple until you learn that unless you also specify /UE:* then /UI always migrates all profiles regardless of arguments supplied. You must always use /UE:* if using /UI.
- /UE (User Exclude) blocks migrating profiles as expected, but it is always overridden by /UEL and /UE.
- /UEL (User Exclude based on last Logon) migrates profiles based on “newer than” rules; either a date or a number of days. Meaning that if a user’s NTUSER.DAT has been modified within the time or date, that profile will be included in migration. /UEL always supersedes /UE.
- You don’t have to include /UI if you’re using/UEL or /UE. If you’re blocking one thing – like if I only want to block local using /UE:%computername%\* – leaving the /UI off is sufficient and less confusing.
- All users are implicitly migrated. So not providing any switches gets everyone.
Returning to the scenario above, we now know what happened:
- /UI was set for all domain users, meaning all domain users will migrate despite /UEL.
- /UEL would have blocked local users from migrating, but those accounts had logged on recently.
- Because the local users were included and (naturally) did not exist on the destination computer, loadstate required the /LAC switch to recreate them.
One more insidious point: by running a scanstate on a computer – even if you have various profile filters listed and even if you cancel the scanstate from completing the examination phase – all of the profiles are loaded and unloaded. Meaning that if you run scanstate even once, /UEL will no longer work because all of your NTUSER.DAT files are modified to “right now”.
When testing UEL be sure to keep one of those handy “file date modification” utilities close. I use an internal one here called FILEDATE.EXE, but there are a zillion similar freebies on the internet (often with the same name). All you need to do is change the date on a given NTUSER.DAT to make it “stale” to USMT.
Making it work
You know how I like to ramble on about how things work and why they do what they do. Many readers just want the fix so they can get back to
YouTube work. No one says you have to use the same command-line on your scanstate and loadstate. In this case, that’s the solution:
Scanstate the source computer using only /UEL. This meets the need for only getting current profiles. This may catch some local user profiles but a local user is unlikely to have much data to migrate. It’s also unlikely that a local user is in regular use in a domain environment, meaning /UEL probably catches it as well. For example:
Scanstate c:\store /uel:90 /i:migdocs.xml /i:migapp.xml
Even in my example where a local user was gathered above, it added only 25MB to each store when using a Windows 7 source computer (due to the default Windows Mail files created for all users). If I had used a hardlink migration, it wouldn’t even have been that. In reality, my local profiles were quite stale as I had not used them since creating the computer – I had to log on to them to make them “fresh” for my example. J
Loadstate the destination computer using /UI and /UE. This prevents the restore of any local profiles captured earlier. Since I only catch “fresh” profiles in the scanstate, there’s no need to provide /UEL here. For example:
Loadstate c:\store /ue:* /ui:cohowinery\* /i:migdocs.xml /i:migapp.xml
With that I finally meet the goal of only migrating domain users that have logged on within the past 90 days.
Note: If the source and destination computer names are identical (perhaps a wipe and load scenario), you could alternatively use:
Loadstate c:\store /ue:%computername%\* /i:migdocs.xml /i:migapp.xml
To wrap up the USMT rules: nothing means everything, something means everything except when it means nothing, and sometimes often means never. Simple!
- More detail and examples on all of this here:
- I used /C a few times for ease of repro. Microsoft still recommends using a config.xml file with error handling rules rather than arbitrarily bypassing non-fatal errors with /c.
- There is a paradox Easter egg in my examples. Whoever points it out in the Comments first gets the “AskDS Silverback Alpha Geek Crown”, currently worn by Darkseid64.
Until next time.
Ned “U-Haul” Pyle