WinRE: ELI5 MDT ZTIWinRE.wsf and Step Add Windows Recovery (WinRE)


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).

7-9-2015 11-31-03 AM


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

7-9-2015 11-54-16 AM

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

DO NOT USE IT!

Advertisements