This is a copy of a post I made at the MDT TechNet forums, I hope you find it useful:
The question "How do I use MDT to perform an offline USMT migration under Windows PE" seems to be a recurring one around here. I know it’s something I have personally struggled with. To my knowledge no real solution to this conundrum has been posted on this forum (yet). Instead of sitting around and moping about it I decided to make my own. After a lot of research, trial and error I was able to create a standalone custom task sequence that will perform offline USMT migrated under Windows PE. To give credit where credit is due I do want to point out that I used the following SCCM-specific guides as starting points:
However I think you’ll see my solution has morphed into its own entity almost entirely. The task sequence itself simply does a USMT capture in offline mode and almost all the settings are controlled using the standard USMT-related variables in CS.ini. It does not deploy an OS or run Loadstate to restore (as I perform those tasks separately). Also I did it this way on purpose to keep it simple (KISS right?). Feel free to add, modify or suggest changes to it as needed (comments by more knowledgeable people are very welcome). Obviously I offer this with no warranties or guarantees. It may not be the BEST solution but it was the best I could come up with. If anyone can improve upon it please feel free to post those improvements here so we can all learn something. To my knowledge the only real dependencies it has is that the offline drive you are migrating has to be assigned a drive letter in the range "C-G" (the task sequence will search these drives in alphabetical order for a "Windows" directory and start migrating the first one it finds). Also an "Offline.xml" specifying your drive letter range needs to be included in your USMT x64 & x86 folders (covered further down) at %DeployRoot%.
CS.ini variables required by the task sequence:
(I have a few values I'm using listed but obviously you could customize these to whatever you want).
Part of running USMT in offline mode involves specifying the path to the Windows directory of the drive you wish to migrate. There are 2 methods:
/offline: <path to offline.xml>:
This command-line option enables the offline-migration mode and requires a path to an Offline.xml configuration file.
/offlineWinDir: <Windows directory>:
This command-line option enables the offline-migration mode and starts the migration from the location specified. It is only for use in Windows PE offline scenarios where the migration is occurring from a Windows directory.
More information on this subject can be found here:
Of these methods I prefer using an offline.xml file to detect the Windows dir in my drive range (C-G) as it seems to offer the greatest level of flexibility. If you want to use /offlineWinDir just edit the part of the task sequnece that references offline.xml to reference your desired /offlineWinDir location instead it and make sure you aslo disable offline.xml.
The USMT Offline.xml file:
(Copy and paste the following into your own offline.xml and save copies to both the x86 and x64 folders in your USMT folder at %DeployRoot%).
<!-- Scan a range of drive letters for a Windows partition to migrate in offline mode. -->
<offline>
<winDir>
<path>C:\Windows</path>
<path>D:\Windows</path>
<path>E:\Windows</path>
<path>F:\Windows</path>
<path>G:\Windows</path>
</winDir>
<failOnMultipleWinDir>1</failOnMultipleWinDir>
</offline>
To use just open the deployment workbench and create a new custom task sequence. Close the workbench and browse to the task sequence location (usually <MyDeploymentShare>\Control\<MyCustomTaskSequenceID>\). Locate "ts.xml" (which should be the only file you see in the task sequence ID folder). Open it in a text editor and replace the code in that task sequence with the code between the lines below:
<?xml version="1.0" encoding="utf-8"?>
<sequence version="3.00" name="Custom Task Sequence" description="Sample Custom Task Sequence">
<group name="Initialization" disable="false" continueOnError="false" description="Initialize the TS environment" expand="true">
<step type="BDD_Gather" name="Gather local only" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">
<defaultVarList>
<variable name="GatherLocalOnly" property="GatherLocalOnly">true</variable>
<variable name="RulesFile" property="RulesFile"></variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTIGather.wsf"</action>
</step>
</group>
<group expand="true" name="State Capture (Offline)" description="" disable="false" continueOnError="false">
<action />
<step type="SMS_TaskSequence_SetVariableAction" name="Set USMT Architecture Path (x86)" description="Determine if the x86 version of Windows PE is running and set %USMTARCH% accordingly." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">USMTArch</variable>
<variable name="VariableValue" property="VariableValue">x86</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_VariableConditionExpression">
<variable name="Variable">Architecture</variable>
<variable name="Operator">equals</variable>
<variable name="Value">x86</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set USMT Architecture Path (x64)" description="Determine if the x64 version of Windows PE is running and set %USMTARCH% accordingly." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">USMTArch</variable>
<variable name="VariableValue" property="VariableValue">x64</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_VariableConditionExpression">
<variable name="Variable">Architecture</variable>
<variable name="Operator">equals</variable>
<variable name="Value">x64</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set Offline System Partition (C:)" description="If a Windows folder is found at a given drive letter set %OfflineSystemDrive% to that drive letter so the USMT files and folders can be cached there." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OfflineSystemDrive</variable>
<variable name="VariableValue" property="VariableValue">C:</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">C:\Windows</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set Offline System Partition (D:)" description="If a Windows folder is found at a given drive letter set %OfflineSystemDrive% to that drive letter so the USMT files and folders can be cached there." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OfflineSystemDrive</variable>
<variable name="VariableValue" property="VariableValue">D:</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">D:\Windows</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set Offline System Partition (E:)" description="If a Windows folder is found at a given drive letter set %OfflineSystemDrive% to that drive letter so the USMT files and folders can be cached there." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OfflineSystemDrive</variable>
<variable name="VariableValue" property="VariableValue">E:</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">E:\Windows</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set Offline System Partition (F:)" description="If a Windows folder is found at a given drive letter set %OfflineSystemDrive% to that drive letter so the USMT files and folders can be cached there." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OfflineSystemDrive</variable>
<variable name="VariableValue" property="VariableValue">F:</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">F:\Windows</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set Offline System Partition (G:)" description="If a Windows folder is found at a given drive letter set %OfflineSystemDrive% to that drive letter so the USMT files and folders can be cached there." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OfflineSystemDrive</variable>
<variable name="VariableValue" property="VariableValue">G:</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">G:\Windows</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set USMT Platform Architecture (32-Bit)" description="Determine if the offline system is a 32-bit Windows version and set %MIG_OFFLINE_PLATFORM_ARCH% accordingly." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">MIG_OFFLINE_PLATFORM_ARCH</variable>
<variable name="VariableValue" property="VariableValue">32</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="not">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">%OFFLINESYSTEMDRIVE%\Program Files (x86)</variable>
</expression>
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">%OFFLINESYSTEMDRIVE%\Windows\SysWOW64</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set USMT Platform Architecture (64-Bit)" description="Determine if the offline system is a 64-bit Windows version and set %MIG_OFFLINE_PLATFORM_ARCH% accordingly." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">MIG_OFFLINE_PLATFORM_ARCH</variable>
<variable name="VariableValue" property="VariableValue">64</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
<condition>
<operator type="and">
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">%OFFLINESYSTEMDRIVE%\Program Files (x86)</variable>
</expression>
<expression type="SMS_TaskSequence_FolderConditionExpression">
<variable name="Path">%OFFLINESYSTEMDRIVE%\Windows\SysWOW64</variable>
</expression>
</operator>
</condition>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set State Store Location" description="Set %OSDStateStorePath% to
Share%\Ýir% so path names can be controlled by CS.ini (this will store migration data created by ScanState)." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">OSDStateStorePath</variable>
<variable name="VariableValue" property="VariableValue">
Share%\Ýir%</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
</step>
<step type="SMS_TaskSequence_RunCommandLineAction" name="Create State Store Location" description="If it does not already exist then create a folder to store the user state migration files that will be generated by ScanState." disable="false" continueOnError="false" startIn="" successCodeList="0 3010" runIn="WinPEandFullOS">
<defaultVarList>
<variable name="PackageID" property="PackageID"></variable>
<variable name="RunAsUser" property="RunAsUser">false</variable>
<variable name="SMSTSRunCommandLineUserName" property="SMSTSRunCommandLineUserName"></variable>
<variable name="SMSTSRunCommandLineUserPassword" property="SMSTSRunCommandLineUserPassword"></variable>
<variable name="LoadProfile" property="LoadProfile">false</variable>
</defaultVarList>
<action>cmd.exe /c if not exist "%OSDSTATESTOREPATH%" md "%OSDSTATESTOREPATH%"</action>
</step>
<step type="SMS_TaskSequence_RunCommandLineAction" name="Cache USMT Files and Scripts" description="Copy USMT component files and scripts to a temporary location on the offline system partition." disable="false" continueOnError="false" startIn="" successCodeList="0 3010" runIn="WinPEandFullOS">
<defaultVarList>
<variable name="PackageID" property="PackageID"></variable>
<variable name="RunAsUser" property="RunAsUser">false</variable>
<variable name="SMSTSRunCommandLineUserName" property="SMSTSRunCommandLineUserName"></variable>
<variable name="SMSTSRunCommandLineUserPassword" property="SMSTSRunCommandLineUserPassword"></variable>
<variable name="LoadProfile" property="LoadProfile">false</variable>
</defaultVarList>
<action>xcopy "%DEPLOYROOT%\USMT\%USMTARCH%\*" "%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%" /herciy</action>
</step>
<step type="SMS_TaskSequence_SetVariableAction" name="Set USMT Working Directory" description="Set the USMT working directory variable to the temporary location on the offline system partition where the USMT component files and scripts were copied." disable="false" continueOnError="false" successCodeList="0 3010">
<defaultVarList>
<variable name="VariableName" property="VariableName">USMT_WORKING_DIR</variable>
<variable name="VariableValue" property="VariableValue">%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%</variable>
</defaultVarList>
<action>cscript.exe "%SCRIPTROOT%\ZTISetVariable.wsf"</action>
</step>
<step type="SMS_TaskSequence_RunCommandLineAction" name="Capture User State (Offline)" description="Perform an offline USMT capture by running ScanState commands using variables in this task sequence, USMT-specific variables in CS.ini and an Offline.xml file." disable="false" continueOnError="false" startIn="" successCodeList="0 3010" runIn="WinPEandFullOS">
<defaultVarList>
<variable name="PackageID" property="PackageID" />
<variable name="RunAsUser" property="RunAsUser">false</variable>
<variable name="SMSTSRunCommandLineUserName" property="SMSTSRunCommandLineUserName"></variable>
<variable name="SMSTSRunCommandLineUserPassword" property="SMSTSRunCommandLineUserPassword"></variable>
<variable name="LoadProfile" property="LoadProfile">false</variable>
</defaultVarList>
<action>"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\Scanstate.exe" "%OSDSTATESTOREPATH%" %SCANSTATEARGS% /i:"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\MigApp.xml" /i:"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\MigUser.xml" /i:"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\MigCustomData.xml" /config:"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\MigCustomConfig.xml" /offline:"%OFFLINESYSTEMDRIVE%\USMTFiles\%USMTARCH%\Offline.xml" /l:"%OFFLINESYSTEMDRIVE%\MININT\SMSOSD\OSDLOGS\USMTcapture.log" /progress:"%OFFLINESYSTEMDRIVE%\MININT\SMSOSD\OSDLOGS\USMTcapture.prg"</action>
</step>
<step type="SMS_TaskSequence_RunCommandLineAction" name="Clean Up USMT Files and Scripts" description="Remove any remaining temporary USMT component files and scripts from the offline system partition." disable="false" continueOnError="false" startIn="" successCodeList="0 3010" runIn="WinPEandFullOS">
<defaultVarList>
<variable name="PackageID" property="PackageID"></variable>
<variable name="RunAsUser" property="RunAsUser">false</variable>
<variable name="SMSTSRunCommandLineUserName" property="SMSTSRunCommandLineUserName"></variable>
<variable name="SMSTSRunCommandLineUserPassword" property="SMSTSRunCommandLineUserPassword"></variable>
<variable name="LoadProfile" property="LoadProfile">false</variable>
</defaultVarList>
<action>cmd.exe /c rd "%OFFLINESYSTEMDRIVE%\USMTFiles" /s /q</action>
</step>
</group>
</sequence>
NOTE: This task sequence relies on another file named "Offline.xml". See my very first post above for details on creating thus file and where to put it.
Any constructive comments/criticism regarding my solution is welcome and greatly appreciated.
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.
Hey guys,
This is a copy of a post I made at the MDT TechNet forums, I hope you find it useful:
The question "How do I use MDT to perform an offline USMT migration under Windows PE" seems to be a recurring one around here. I know it’s something I have personally struggled with. To my knowledge no real solution to this conundrum has been posted on this forum (yet). Instead of sitting around and moping about it I decided to make my own. After a lot of research, trial and error I was able to create a standalone custom task sequence that will perform offline USMT migrated under Windows PE. To give credit where credit is due I do want to point out that I used the following SCCM-specific guides as starting points:
http://www.windows-noob.com/forums/index.php?/topic/1735-using-offline-mode-in-windows-pe-using-usmt-4-via-a-task-sequence-in-sccm-2007-sp2/
http://www.petervanderwoude.nl/post/capture-user-files-and-settings-offline-winpe-or-online-fullos-with-configmgr-2007/
However I think you’ll see my solution has morphed into its own entity almost entirely. The task sequence itself simply does a USMT capture in offline mode and almost all the settings are controlled using the standard USMT-related variables in CS.ini. It does not deploy an OS or run Loadstate to restore (as I perform those tasks separately). Also I did it this way on purpose to keep it simple (KISS right?). Feel free to add, modify or suggest changes to it as needed (comments by more knowledgeable people are very welcome). Obviously I offer this with no warranties or guarantees. It may not be the BEST solution but it was the best I could come up with. If anyone can improve upon it please feel free to post those improvements here so we can all learn something. To my knowledge the only real dependencies it has is that the offline drive you are migrating has to be assigned a drive letter in the range "C-G" (the task sequence will search these drives in alphabetical order for a "Windows" directory and start migrating the first one it finds). Also an "Offline.xml" specifying your drive letter range needs to be included in your USMT x64 & x86 folders (covered further down) at %DeployRoot%.
CS.ini variables required by the task sequence:
(I have a few values I'm using listed but obviously you could customize these to whatever you want).
Offline.xml and offlineWinDir:
Part of running USMT in offline mode involves specifying the path to the Windows directory of the drive you wish to migrate. There are 2 methods:
/offline: <path to offline.xml>:
This command-line option enables the offline-migration mode and requires a path to an Offline.xml configuration file.
/offlineWinDir: <Windows directory>:
This command-line option enables the offline-migration mode and starts the migration from the location specified. It is only for use in Windows PE offline scenarios where the migration is occurring from a Windows directory.
More information on this subject can be found here:
http://technet.microsoft.com/en-us/library/ee126219(WS.10).aspx
Of these methods I prefer using an offline.xml file to detect the Windows dir in my drive range (C-G) as it seems to offer the greatest level of flexibility. If you want to use /offlineWinDir just edit the part of the task sequnece that references offline.xml to reference your desired /offlineWinDir location instead it and make sure you aslo disable offline.xml.
The USMT Offline.xml file:
(Copy and paste the following into your own offline.xml and save copies to both the x86 and x64 folders in your USMT folder at %DeployRoot%).
--------------------------------------------------------------------------
--------------------------------------------------------------------------
The USMT Offline Migration Task Sequence:
To use just open the deployment workbench and create a new custom task sequence. Close the workbench and browse to the task sequence location (usually <MyDeploymentShare>\Control\<MyCustomTaskSequenceID>\). Locate "ts.xml" (which should be the only file you see in the task sequence ID folder). Open it in a text editor and replace the code in that task sequence with the code between the lines below:
--------------------------------------------------------------------------
--------------------------------------------------------------------------
NOTE: This task sequence relies on another file named "Offline.xml". See my very first post above for details on creating thus file and where to put it.
Any constructive comments/criticism regarding my solution is welcome and greatly appreciated.
Share this post
Link to post
Share on other sites