Now I should first post about what WinRE is before writing this, but most of us know what it is so I will address that later. This post will focus on MDT and the implementation of ZTIWinRE.wsf that is referenced in the Task Sequence Step Add Windows Recovery (WinRE).
If you don’t want to take the time for my ELI5 (Explain Like I’m 5), then how about a summary:
DO NOT USE IT!
Ok. Now for the ELI5. For starters, in MDT there is a Step in the default Client Task Sequence called Add Windows Recovery (WinRE). This is in the Postinstall phase. As you can see it is a simple Run Command Line entry to run ZTIWinRE.wsf (in the Scripts directory).
So the Task Sequence tells us nothing, but we can look into the ZTIWinRE.wsf itself. Now reading line 81, it tells us that if we did not set PrepareWinRE = YES (case insensitive) in our CustomSettings.ini, then this step will be skipped. SO DO NOT ADD PrepareWinRE = YES TO YOUR CUSTOMSETTINGS!
If UCase(oEnvironment.Item("PrepareWinRE")) <> "YES" then oLogging.CreateEntry "WinRE is not enabled, Skip.", LogTypeInfo Main = SUCCESS Exit function
If the image we are deploying is Windows Vista or Older (identified by the first three characters of ImageBuild, returning lower than 6.1), then again this script will exit.
ElseIf Left(oEnvironment.Item("ImageBuild"),3) < "6.1" then oLogging.CreateEntry "WinRE is not supported on Vista or Older. Skip.", LogTypeInfo Main = SUCCESS Exit function
And finally if the image we are deploying is Windows 7 (identified by the first three characters of ImageBuild, returning 6.1), this won’t work anyway and this script will exit.
ElseIf Left(oEnvironment.Item("ImageBuild"),3) = "6.1" and Left(oEnvironment.Item("OSCurrentVersion"),3) > "6.1" then oLogging.CreateEntry "WinRE cannot be enabled for Windows 7 when using Windows PE from ADK due to compatibility issue with ReAgentC.exe, skipping.", LogTypeInfo Main = SUCCESS Exit function End if
So apparently this will only work for Windows 8.1 or newer(ish). The script will next check to make sure we have a Boot Drive
oLogging.CreateEntry "Ensure boot drive has a Drive Letter.", LogTypeInfo bUnMapDrive = false set oDiskPart = GetBootDriveEx ( false, "", true ) If oDiskPart is Nothing then bUnMapDrive = true oLogging.CreateEntry "The drive letter for the boot partition was not found.", LogTypeInfo set oDiskPart = GetBootDriveEx ( true, "", true ) TestAndFail not oDiskPart is nothing, 10501, "Verify a boot drive object was returned." oLogging.CreateEntry "Found Object: " & oDiskPart.oWMIDiskPart.Path_, LogTypeInfo End if TestAndFail oDiskPart.Drive <> "", 10502, "Verify a drive was returned: " & oDiskPart.Drive
It will set the destination WinRE.wim to the Boot Drive in \Recovery\WindowsRE\WinRE.wim. After that it will do a FindFile of WinRE.wim to see if it can locate the file. FindFile is a function of ZTIUtility.vbs and will look for the WinRE.wim in the Deployment Share (Root, Tools, Servicing, Scripts, etc).
sTargetPath = left(oDiskPart.Drive,2) & "\Recovery\WindowsRE\WinRE.wim" oLogging.CreateEntry "Target file: " & sTargetPath, LogTypeInfo ' Force BCDBootDrive oUtility.VerifyPathExists and t oFSO.GetParentFolderName(sTargetPath) iRC = oUtility.FindFile("WinRE.wim", sFoundPath)
Now this is the not so bright part. Even if I have an existing C:\Windows\System32\Recovery\WinRE.wim where it should be, the script will not find it and will proceed to copying the LiteTouch.wim to my Boot Drive Partition
If iRC <> SUCCESS then sFoundPath = oEnvironment.Item("DeployRoot") & "\Boot\LiteTouchPE_" & sArchitecture & ".wim" End if TestAndFail oFSO.FileExists( sFoundPath ), 10503, "Verify File: " & sFoundPath If oFSO.FileExists( sTargetPath ) then oUtility.RunWithConsoleLogging "cmd.exe /c attrib -S -H """ & sTargetPath & """" End if oFileHandling.CopyFile sFoundPath, sTargetPath, true
Trust me this is NOT what you want it to do. The remainder of the script will run REAgentC to enable the WinRE.wim.
iRC = oUtility.FindFile("REAgentC.exe",sREAgentC) If iRC = SUCCESS then oLogging.CreateEntry "Found REAgentC.exe: " & sREAgentC, LogTypeInfo ElseIf ucase(oEnv("Processor_Architecture")) = "X86" and oFSO.FileExists( sTargetOSDrive & "\Windows\SysWOW64\REAgentC.exe") then sREAgentC = sTargetOSDrive & "\Windows\SysWOW64\REAgentC.exe" ElseIf oFSO.FileExists( sTargetOSDrive & "\Windows\System32\REAgentC.exe") then sREAgentC = sTargetOSDrive & "\Windows\System32\REAgentC.exe" End if TestAndFail not isempty(sREAgentC), 10504, "Verify REAgentC.exe is found" oUtility.RunWithConsoleLogging sREAgentC & " /info" & sTargetOS oUtility.RunWithConsoleLogging sREAgentC & " /disable" oUtility.RunWithConsoleLogging sREAgentC & " /info" & sTargetOS oUtility.RunWithConsoleLogging sREAgentC & " /setreimage /path """ & oFSO.GetParentFolderName(sTargetPath) & """" & sTargetOS & sBootKey oUtility.RunWithConsoleLogging sREAgentC & " /info" & sTargetOS oUtility.RunWithConsoleLogging sREAgentC & " /enable" oUtility.RunWithConsoleLogging sREAgentC & " /info" & sTargetOS
Now was any of this necessary? Absolutely not. In my next few posts, I’ll help detail why Windows does this on its own anyway.
So I will say again when it comes to ZTIWinRE.wsf