Recently I have been tasked with creating another task sequence to capture and rebuild a Windows 7 workstation using USMT. As I have previously built our XP to Windows 7 migration task sequence, I was well aware of what to do; however, I thought it was cumbersome to do the same thing for a system rebuilt type of scenario, and not a complete OS migration.
I have in the past created a little batch script that would allow me to use USTM executables manually outside of SCCM, but unfortunately I forgot to back them up when we moved on from SCCM 2007 to SCCM 2012. The idea is to have an IT person go to the users computer, backup their profile, and then restore it, the easiest way possible.
Not wanting to invest time in recreating a simple batch script with no user interface, I started looking around for a GUI based USMT product. There are a few different GUIs out there that basically put a pretty face on USMT commands, however, those that looked good were not free, and those that were free, well, were not very good. I did stumble onto one GUI that looked very professional and minimalistic, yet had a bunch of great features built in that made it "smart". Workstation Migration Assistant by Dan Canningham seemed the fit the bill.
I downloaded the program and configured the MigAssistant.exe.config file with the settings I would like, including my designated USMT data store. This datastore is used to save the backups, as well as restore from, all without having to specify anything within the app. This is great as it makes it very easy for a desktop administrator to simply backup and restore, without having to worry about where the files are placed ect. Using the config file I was able to make this my default selection within the app:
I tried running the program as my slightly elevated standard account on my desktop and it ran perfectly. I was then able to restore the information on another machine and everything worked great. I thought that I have found the perfect tool, I could run it as the user, backup the data, and be on my way; however, when I tried to do the backup as a standard user with no system rights, I was prompted for the admin account. This in itself isn't bad; however, the default configuration of "I am the only person who uses this Workstation" that I wanted to use no longer worked, as the system tried to backup the profile of the admin account I entered to let it run in the first place. To top it off, every time I opened the program even as an administrative user, it would always prompt with the UAC prompt to allow the program to run.
Because I really liked the program and wanted it to be as simple as possible for our staff, I decided to do some digging to see why the UAC prompt was popping up, and how to make the program run as a standard user.
During my research I found that when a program is compiled, the "requestedExecutionLevel" is what controls the UAC prompts, which decides if you should enter admin credentials to run the program or not. The source code for Workstation Migration Assistant was available on Dan's website, but I haven't touched any development tools in ages and would be lost trying to recompile the original source code. Remembering a tool I used back in the day, I thought I would give Resource Hacker a shot and see if I can do anything within that tool to modify the MigAssitant.exe file from Dan's program. I loaded up Resource Hacker and opened the MigAssistant.exe file, and low and behold, under a strange entry of 24>1>0 I found exactly what I was looking for
<?xml version="1.0" encoding="utf-8"?>Right there, not only does it show the exact field I was hoping to change, it also shows just above the various possible execution levels that I can set! I changed the "requireAdministrator" field to "asInvoker", pressed the compile button, followed by a save, and ran the executable, and to my surprise, Migration Assistant opened without a single prompt for even the most basic user! Now, I knew the real test would come with being actually able to backup and do the restore, so I was only a third of the way there, at best.
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" />
<requestedExecutionLevel level="highestAvailable" />
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="requireAdministrator" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
</asmv1:assembly>
As expected, trying to run the backup and restore procedures failed, with the logs pointing to permissions, as scanstate.exe and loadstate.exe that this program calls require admin rights to actually capture and restore the profile. So I did what I thought would be crazy if it worked, and opened up both scanstate.exe and loadstate.exe using Resource Hacker, and under the same strange grouping of 24 > 1 > ## I found the execution level assignment for both loadstate.exe and scanstate.exe.
<?xml version='1.0' encoding='utf-8' standalone='yes'?>Running a program asInvoker means that it will run in the user context, and if that user has no rights to do what is needed, the program will fail to execute. So I decided to try out "requireAdministrator" as the execution level within scanstate.exe and loadstate.exe, compiled the script and saved the executables. I did not expect it to work, but to my surprise, it worked even better than I expected!
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0"
>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
With the user logged in, we are able to now open the program without any prompts, and simply press "Start", at which point scanstate.exe is called, and a prompt for administrator password is required. We enter our administrator password, and off it goes, backing up the original user who opened the Migration Assistant in the first place, and not the administrator who allowed the action. Restore works exactly the same way, asking for the administrator password to continue. The great thing about this GUI is that is even has a drop down box should you have multiple backups, and allows you to select which one you would like to restore. The program automatically looks for all the backups performed by this user using the _userID naming context and gives you the option to restore any of the backups you have, from any other computer.
I have attached the full program below with the modified MigAssistant.exe and scanstate.exe and loadstate.exe files. Extract the bundle, make the proper changes within the MigAssistant.exe.config file, and it should be ready to use!
Hope you guys find this info, and especially the tool as useful as I have. Big props to Dan for making this awesome GUI.
DOWNLOAD