Posts Tagged ‘WinPE’

The Mysterious Case of the Un-Deletable MBR (Or, More Reasons to Hate PGP)

Shortly after releasing MDT 2012 on the general public I got a call from a colleague who told me that his LiteTouch deployment was failing.  He was able to boot to LiteTouch media, go though the configuration wizard, and initiate setup.  LiteTouch would partition the drive, Windows Setup would start, the image would get written to the computer, and then the system would reboot… so far so good. What happened next was unexpected.  The computer booted to the PGP BootGuard screen.

Turns out we were dealing with a system that had been encrypted using PGP Whole Disk Encryption. However, we have a lot of those, and deployment has not failed on them before.  In the past, LiteTouch dutifully has erased the Master Boot Record (MBR) and all existing partition tables on the system, effectively wiping PGP BootGuard from the machine before running Windows Setup.

So what changed?  Is this a bug in MDT 2012?  Something new in PGP Desktop version 10.2.0 MP4?  Or a configuration problem in our LiteTouch environment.

Let’s omit the details of ~6 hours of troubleshooting… it was a change in the WinPE LiteTouch environment, and PGP.  It appears, though investigation, that the PGP filter drivers attempt to block access to the MBR of the hard drive.  Since I had injected PGP drivers into the LiteTouch 32-bit boot media, I had, effectively created a situation where DiskPart.exe would be unable to remove PGP BootGuard from the system.  The really irritating part is that the PGP drivers do not pass any indication to the Windows utilities that there has been an error writing to the MBR.  DiskPart.exe, BootSect.exe, and the DaRT Disk Commander all can be used to repair MBRs.  But when used in a PGP-enabled environment they all report success in manipulating the disk MBR, but all of them fail to make any real change to the true MBR.  How do you usually erase a drive?  For me, I would run “diskpart.exe, select disk 0, clean”.  With PGP drivers in place, you could run this series of commands, think that you had erased the drive, but still end up with PGP BootGuard in your MBR.  It really is maddening.

Symantec/PGP claim that you can remove the MBR data by “deinstrumenting” the disk using the “pgpwde.exe” command.  The problem with this is, pgpwde will not let you deinstrument an encrypted drive.  So, you would have to decrypt the drive first, then deinstrument.  I am not wasting time on that.  Worse yet, if your drive was partially encrypted when you erased the data partition, PGPWDE still reports the drive status as “partially encrypted”, and refuses to perform any actions on the drive (such as “deinstrument”) until the current encryption (on the nonexistent drive) completes.  AARGH!

Fortunately, I was able to find a low-level disk manipulation utility that actually works in 32-bit PGP-enabled WinPE environments.  PlDD.exe:

http://home.comcast.net/~plavarre/plscsi/tools/pldd/

There are other “DD” equivalents for Windows.  Most of them either fail to work against PGP (GnuWin32 DD.exe and the Crysocome DD), or will not function under WinPE (FAU DD).  PlDD is pretty old, and it does not work under 64-bit Windows.  But, we don’t need 64-bit support (PGP does not provide 64-bit drivers for WinPE!), it works perfectly in 32-bit Windows.  Thus, this is the perfect tool for the time being.

Getting the right command syntax to pldd.exe was a bit challenging as the tool itself has scarce documentation.  I wish I could credit all of the resources that I used to put this dense command together, but I have since lost the browser tabs.  The following is the pldd.exe command, suitable for plugging into an MDT task sequence as a custom command:

cmd.exe /c “%SCRIPTROOT%\Pldd.exe if of=\\.\PhysicalDrive0 bs=512 count=1″

Argument breakdown:

  • if = In File.  In this version of DD, if provided with parameters, will use a string of zeros as input.
  • of = Out file.  In this case, we are using the Windows device path “\\.\PhysicalDrive0″, which is fixed disk zero.  I think this device path is referenced in the gnuwin32 dd docs.
  • bs = Block size.  We are choosing to write in 512 byte blocks.
  • count = The number of blocks to write.  We are going to write one 512 byte block to the “out file”.

To summarize, we use pldd to write 512 bytes of zeros to the start of physical drive zero.  This action wipes out the MBR and the disk signature of the drive (sorry, I lost my reference for this factoid, too).  Zeroing 512 bytes of disk is rather faster than zeroing the entire drive, which is the only other option I have seen referenced in the tubes for fixing this issue.

Share and Enjoy.

MDT 2012 – Taking LiteTouch Offline

I decided to give some of my user base something that they have been asking for for a long time… the ability to run MDT/LiteTouch deployments entirely from removable storage media. I had avoided doing this in the past as we made significant use of the MDT database in selecting hardware-specific support applications (such as Dell QuickSet).  However, with MDT 2012 (and the general deprecation of hardware-specific support software under Windows 7), I have decided to abandon the MDT database.  This makes generation of offline MDT media much more feasible.

“I should be able to get this done in a few hours!”, I thought.  Ha!  Four days later…

Gotchas in adding LiteTouch Offline media to a previously online-only environment:

Expiring stale media:

One of the leading arguments we make to persuade users to adopt the use of LiteTouch is that “we keep it up to date for you”.  What about offline media?  How to we ensure that that stays current?  One of the Brad Tucker, Deployment Guy, has a solution for that:

http://blogs.technet.com/b/deploymentguys/archive/2012/02/15/expiring-outdated-stand-alone-media.aspx

The problem there is that his script was developed for the SCCM ZTI scenatio, not LiteTouch.  However, with a little work I was able to adapt his script for use in LiteTouch.  The script body is available below.  To run it, I needed to modify the “winpeshl.ini” file in %ProgramFiles%\Microsoft Deployment Toolkit\Templates as follows:

[LaunchApps]
%SYSTEMROOT%\System32\wscript.exe,X:\Deploy\Scripts\ZUVMExpiredMediaCheck.vbs
%SYSTEMROOT%\System32\bddrun.exe,/bootstrap

The script referenced above (ZUVMExpiredMediaCheck.vbs) needs to be defined in the “Extra Directory to Include” field in the WinPE section of the Media set in the Deployment Workbench.  You need to include the “\Deploy\Scripts” folder structure in the Extras directory, too.

WinRE installation problems:

Since deploying MDT 2012, I finally worked though the problem of including both WinRE and MS DaRT tools into the LiteTouch boot media, and in the WinRE environment installed with the operating system.  However, with offline media the inclusion we would not want to copy the LiteTouch WinPE instance to disk.  Two reasons.  Firstly, the OS Deployment option simply would not work (Offline media would not be available), and secondly, we just included a script to disable the media.  To solve this problem, I needed to set the “PrepareWinRE” Property in the CustomSettings.ini file for the media set to “NO”.

MS DaRT Integration Problem:

When testing LiteTouch from a fully offline machine, I started to get a “network connection not available” error pop up at seemingly random places after starting up the boot media.  Eventually I realized that the error was coming from the DaRT Remote Connection tool that starts up with WinPE.  While this error does not cause any problems with actual deployment, I don’t want it causing end-user panic, so I decided to see if I could disable the feature.  According to documentation, I need to generate a “DartConfig.DAT” file using the DaRT configuration tool.  DartConfig.DAT is a binary configuration file (not plain text).  It’s options are not documented anywhere, so you really do have to run the GUI tool to generate a new DAT.  You then are supposed to drop the DAT file into “%ProgramFiles%\Microsoft Deployment Toolkit\Templates”, and update your boot media.  A few problems with this:

  1. If you want different configuration files installed into your WinPE instances, you will either to switch out the DartConfig.dat in the Templates directory each time you update boot media, or run the updates from a different MDT instance, or edit the LiteTouch boot WIM files each time you update the boot media.  There is no way to specify different DartConfig.dat files per deployment share or media set.
  2. The Deployment Workbench does not consistently insert the DartConfig.dat file into the LiteTouch boot media.  If you update your DartConfig.dat in the Templates directory, then update your boot media, there is no guarantee that your DartConfig.dat will get updated.  The only sure-fire way to get a new DartConfig in your deployment share seems to be to force regeneration of the boot media (i.e. you need to throw out your existing boot WIM files, not update them).  The situation is worse with offline media sets.  Rather the workbench will copy any existing boot WIMs from the root deployment share to serve as a baseline image when generating offline boot images.  Thus, to update DartConfig.dat in a media set, you need to delete both the root share boot WIMs, and the offline boot WIMs prior to updating media.
  3. You might think that you could work around that whole one-template-per-workbench problem by including a per-media-set DartConfig.dat in the “Extras” folder that you can optionally include in each media set or deployment share.  After all, the media update procedure appears to add the extras after the templates.  But if you did think this, you would be wrong.  The update apparently will not overwrite existing files within the source WIM.
  4. You might, out of sheer desperation, decided to remove DaRT from the offline boot media  by deselecting the component from the WinPE properties of the media set.  This also will fail.  The workbench will report that “DaRT cannot be removed from the media.  Use the -Force option to regenerate the media.”  Presumably the error is suggesting that you should add “-force” to the Update-MDTMedia PowerShell Cmdlet that is used to update the media set.  Sadly, “-Force” is not a valid flag for this cmdlet.

Ultimately, I just used imagex to mount the LiteTouch Offline boot media, and switched out the DartConfig.dat file using a simple “copy” command.  Now I just need to remember to do that every time.

UserExit Script – Required Modifications:

Back in 2008 I added a UserExit script to LiteTouch to generate a semi-unique computer name by taking the last eight characters of the computer’s MAC address, then appending a hyphen and a date string.  It turns out that the routine in MDT that captures the MAC address (presumably ZTIGather.vbs) will not succeed unless the computer has a functional Ethernet connection.  Grrr… When testing LiteTouch offline, we were getting computer names like “Address%-1214″.  Percent characters are not valid in computer names  so, I needed to update our UserExit to use other semi-unique system attributes such as “Serial Number” to “Asset Tag” if the MAC is not available.  I also added a fallback string of “UVMLT” if none of those variables are found.  The new script is available below, along with a sample call to the script from CustomSettings.ini.


' // ****************************************************************************
' // File:      ZUVMExpiredMediaCheck.vbs
' // Version:   1.0
' // Purpose:   Check to see if stand-alone media is expired
' // Actions:   Shuts down WinPE if media is older than iExpAge variable months
' //            Otherwise, script exits with Return 0.
' // Usage:     cscript/wscript ZUVMExpiredMediaCheck.vbs
' //            (to be added to winpeshl.ini, before bddrun.exe)
' // ****************************************************************************
Option Explicit

' // Declare Variables:
Dim cFiles
Dim dtCreationDate, dtEndDate, dtXMonthsAgo
Dim iExpAge
Dim oDiskDrive, oDrives, oExec, oFile, oFSO, oShell, oWMIService
Dim sCommand, sComputer, sExpText, sSysRoot, sUSBPath

' // Initialize Variables:
' Media Expiration Age, in months:
iExpAge = 4

' // -----------------------------------------------------------------------------------------
' // Function: Converts the WMI date query response to a simple date format.  (e.g. 09/21/2010)
Function WMIDateStringToDate(dtmInstallDate)
	WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & Mid(dtmInstallDate, 7, 2) _
	& "/" & Left(dtmInstallDate, 4) & " " & Mid(dtmInstallDate, 9, 2) & ":" _
	& Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, 13, 2))
End Function
' // -----------------------------------------------------------------------------------------

' // ---------------------------------------------------------------------------------
' // Find the environment variable %SYSTEMROOT% for location of LiteTouch Executables.
Set oShell = CreateObject("WScript.Shell")
sSysRoot = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%")
' // ---------------------------------------------------------------------------------

' // --------------------------------
' // Find driver letter for USB Media
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oDrives = oFSO.Drives
For Each oDiskDrive In oDrives
	If oDiskDrive.DriveType = "1" Then
		sUSBPath = oDiskDrive.Path
	End If
Next
' // --------------------------------

' // -------------------------------------------------------------------------
' // Media Check - Check for Applications.xml presence and age.
sComputer = "."
Set oWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
' Query WMI for creation date of the Applications.xml file on the USB Drive:
'    NOTE: Do not add the wbemFlagForwardOnly (Decimal 32) flag to this query.  While the query would run faster
' with the flag, we also will not be able test for empty queries.
Set cFiles = oWMIService.ExecQuery("Select * From CIM_DataFile Where Name = '" & sUSBPath & "\\Deploy\\Control\\Applications.xml'")
' // -------------------------------------------------------------------------

' // ---------------------------------------------------------------------------------
' // If Applications.xml file is not present, this is not offline media.  Exit script.
if cFiles.Count = 0 then
	Wscript.Quit(0)
end if
' // ---------------------------------------------------------------------------------

' // ---------------------------------------------------------------------------------------------
' // If the Applications.xml file creation date is more than "iExpAge" months ago, shutdown WinPE.
For Each oFile in cFiles
	dtCreationDate = WMIDateStringToDate(oFile.CreationDate)
	dtEndDate = DateAdd("m", iExpAge, dtCreationDate)
	' Set the date iExpAge months ago from today
	dtXMonthsAgo = DateAdd("m", -iExpAge, Now)
	If dtCreationDate < dtXMonthsAgo then
		' Expiration Text, to be displayed to the user if older than iExpAge months:
		sExpText = "This LiteTouch Offline Media expired on: " & dtEndDate & chr(13) _
			& "Refresh your media using the README file located here:" & chr(13) _
			& "\\files.uvm.edu\software\Windows_Deployment_Services"
		MsgBox sExpText,vbMsgBoxSetForeground,"Expired Media"
		'Shutdown WinPE immediately:
		sCommand = sSysRoot & "\system32\wpeutil.exe shutdown"
		set oExec = oShell.Exec(sCommand)
	Else
		' If the media is fresh, run LiteTouch Offline.
		WScript.Quit(0)
	End If
Next
' // ---------------------------------------------------------------------------------------------

' // ZUVMUserExit.vbs
' // Custom Function library for use with the Microsoft Deployment Toolkit
' // Currently includes "GenUniComp" - a function for generating unique computer names

' code adapted from source content:
'   http://blogs.technet.com/benhunter/archive/2007/03/17/understanding-bdd-rule-processing.aspx

Function UserExit(sType, sWhen, sDetail, bSkip)
	UserExit = Successfs
End Function

Function GenSimDate(sSimDate)
	'Generates a simple date string in the format of YYMMDD
	Dim dNow, sYear, sMonth, sDay
	dNow = Date()
	sYear = Right(cStr(Year(dNow)), 2)
	sMonth = cStr(Month(dNow))
	sDay = cStr(Day(dNow))
	GenSimDate = sYear + sMonth + sDay
End Function

Function CleanMac(sMac)
	'Strips colon (:) characters from the variable passed to this function.  The passed variable is presumed to be a Mac address.
	Dim oRegExp
	Set oRegExp = new RegExp
	oRegExp.IgnoreCase = true
	oRegExp.Global = true
	oRegExp.Pattern = ":"
	CleanMac = oRegExp.Replace(sMac, "")
End Function

Function GenUniComp(sMac,sSerial,sATag)
	'Generates a hopefully unique computer name by:
	'   Selecting from available MacAddress, SerialNumber, or Asset Tag then
	'   triming the right eight digits from the value and appending a hyphen with the current date.
	Dim sSimDate, sUniVal
	oLogging.CreateEntry "ZUVMUserExit: sMac value in UserExit script is: " & sMac,LogTypeInfo
	oLogging.CreateEntry "ZUVMUserExit: sSerial value in UserExit script is: " & sSerial,LogTypeInfo
	oLogging.CreateEntry "ZUVMUserExit: sATag value in UserExit script is: " & sATag,LogTypeInfo
	if InStr(sMac,"%Mac") = 0 then
		oLogging.CreateEntry "ZUVMUserExit: Using Mac Address to generate computer name",LogTypeInfo
		sMac = CleanMac(sMac)
		oLogging.CreateEntry "ZUVMUserExit: Cleaned sMac values now is: " & sMac,LogTypeInfo
		sUniVal = sMac
	elseif InStr(sSerial,"%Serial") = 0 then
		oLogging.CreateEntry "ZUVMUserExit: Using Serial Number to generate computer name.",LogTypeInfo
		sUniVal = sSerial
	elseif InStr(sATTag,"%Asset") = 0 then
		oLogging.CreateEntry "ZUVMUserExit: Using Asset Tag to generate computer name.",LogTypeInfo
		sUniVal = sATag
	else
		oLogging.CreateEntry "ZUVMUserExit: Using Fallback Computer Name",LogTypeInfo
		sUniVal = "UVMLT"
	end if
	oLogging.CreateEntry "ZUVMUserExit: sUniVal now set to: " & sUniVal,LogTypeInfo
	sSimDate = GenSimDate(sSimDate)
	GenUniComp = Right(sUniVal, 8) + "-" + sSimDate
	oLogging.CreateEntry "ZUVMUserExit: Unique Computer Name will be: " & GenUniComp,LogTypeInfo
End Function

Calling the GenUniComp function from CustomSettings.ini:

ComputerName=#GenUniComp("%MacAddress%","%SerialNumber%","%AssetTag%")#

MDT 2012 – The Ultimate WinPE Boot Media

This week I went to rebuild our MS DaRT Emergency Rescue Disk media.  While looking into the available tools to automate injection of our LiteTouch / MDT Deployment Workbench driver store into the DaRT boot media, I discovered something interesting in the MDT 2012 RC1 release notes… MDT 2012 supports the addition of DaRT into the LiteTouch boot media.  Once complete, you will have boot media that will support LiteTouch deployment, Standard WinRE recovery tools, and MS DaRT tools.  Too cool!  Some hours of work and a few gotchas later, it is done.  My LiteTouch media contains LiteTouch scripts, WinRE, DaRT, and PGP command line utilities.  Best of all, rebuilding of the media is sustainable.  Here is how it is done:

  1. Making WinRE available in LiteTouch boot media:
    In the Operating Systems section of the workbench, create a DEV folder.  Add to this one operating system with source files for each architecture that you need boot media for (i.e. amd64 and x86).  The OS version must match the version of WinPE used by the AIK on your build system.  (e.g. If you are using the Windows 7 AIK, you need current Windows 7 sources in the deployment share.)  To avoid trouble, make sure that these are the only operating systems with source files for this version of the AIK (e.g. You can have Vista source files if you need them, but keep only one Win 7 source so you will know which boot.wim is being used to generate your LiteTouch media).
  2. Adding DaRT:
    Follow the directions in the MDT help to install and activate the DaRT tools into the deployment share.
    In the deployment share CustomSettings.ini, set the variable:
    PrepareWinRE=YES
    This will insure that the workbench will generate a combined WinRE/DaRT image.
  3. Adding PGP:
    To make PGP tools available, use the PGPPE tools to apply pgpwde.exe to the boot.wim in the 32-bit operating system source files that you created in step 1, as follows:
    pgppe.exe /vista [pathToOSSource] [pathToPGPFiles]
    This will install PGP tools into both the Windows Setup and WinPE images in the stock boot.wim.  When you generate LiteTouch media from the Workbench, the PGP tools already will be present.
    Documentation on the use of PGPPE can be found here:
    http://www.symantec.com/business/support/index?page=content&id=HOWTO64225&actp=search&viewlocale=en_US&searchid=1332275738030
    and here:
    http://www.symantec.com/business/support/index?page=content&id=TECH149634
    (The first article contains corrections to the second article.  Note that PGPPE now is part of a standard PGP Desktop install, and does not need to be downloaded separately).

Of course, there is a lot more going on with MDT 2012 than just boot media changes… more on that later.

Microsoft Emergency Repair Disk, PGP, and Windows System Recovery

Microsoft Campus Agreement includes access to the Microsoft "Diagnostics and Recovery Toolkit" (DaRT), the chief component of which is the Emergency Repair Disk (ERD).  ERD boot images can be found in the Microsoft Campus Agreement share:
\\files.uvm.edu\mca\Windows\ERD

DaRT is part of the larger Microsoft Desktop Optimization Pack (MDOP).  You can locate the DaRT installer and repair disk generation utility in the MDOP distribution utility:
\\files.uvm.edu\mca\Windows\MDOP_2010\DaRT

The DaRT recovery disk contains many immensely useful utilities, including:

  • Offline Registry Editor
  • NTFS File Restore (undelete utiltiy)
  • Disk Commander (disk repair)
  • Secure Wipe (securely erases a drive)
  • Offline Hotfix Uninstaller
  • System File Consistency (SFC) scanner
  • Offline "Standalone System Sweeper" (malware removal tool)

Those of you who have been using PGP Whole Disk Encryption might be wondering if any of these utilities may be wondering if these sorts of utilities will be at all useful on systems that have been encrypted.  The answer is yes, as long as the boot media has had PGP command line utilities added to it.  We have generated an ERD image with PGP drivers already pre-injected:
ERD65-Win7(32bit)-withPGP.iso

You also can transfer the ERD image to a bootable USB drive by following the directions in the README file here:

Unfortunately, PGP has not (yet) provided command line utilities for 64-bit WinPE environments.  But fortunately, you can use 32-bit WinPE to access 64-bit versions of Windows.  In this case, you will only be able to run a small subset of the ERD utilities against the offline OS.  However, you can decrypt your 64-bit OS using the 32-bit ERD, and then run the 64-bit ERD against the decrypted drive (clearly, this will take a large time commitment).

To access an encrypted disk for use with the DaRT ERD, you may need to "fake out" the ERD boot menu. 

  1. When the system restore process starts, the tool will not be able to detect an Operating System.  Select the "Restore your computer using a system image…" option, as shown below:
    clip_image001 
  2. When the tool fails to detect a restoration image, click "Cancel":
    clip_image002 
  3. Then click "cancel" again.  From the System Recovery Options dialog, select "Command Prompt":
    clip_image003
  4. Once inside the command prompt you can use the "PGPWDE" utility to access your drive. 

Here are some sample PGPWDE commands:

  • "pgpwde.exe –enum" – Take note of the disk numbers of any encrypted drives that you wish to unlock (typically "0" for the first disk on the system).
  • "pgpwde.exe –auth –disk 0 –interactive" – To unlock the disk for direct access by utilities on the DaRT ERD.
  • "pgpwde.exe –decrypt –disk 0 –interactive" – To fully decrypt the disk (note that this can take a long time, and there is no progress indicator).
  • "pgpwde.exe –status –disk 0" – To view the status of a disk encryption or decryption process on a specified drive.

Note that after you have run the "pgpwde.exe –auth" command, you can then re-launch the System Recovery conosle by running the command:

  • winpeshl.exe

You now should be able to launch the Microsoft Diagnostics and Recovery Toolset or use the "System Restore" option in the System Recovery Options dialog, and have full access to the Operating System on the encrypted disk.

Share and enjoy.

WinPE – loading drivers to a live instance

Back in Vista/WinPE2 days, I recall going though some pain trying to load network and storage drivers into a live WinPE instance.  I vaguely recall giving up.  This experience has prevented me from even trying to do such a thing in more recent years.  However, today I really wanted to avoid building new WinPE media just to test the validity of a driver.  Fortunately, it appears WinPE has come a long way…

  1. Get you driver, load it to removable media, connect the media to your running WinPE instance.
  2. “cd” to the driver directory
  3. Run “drvload [path to inf file]“
  4. If you just loaded a network driver, run “wpeutil initializeNetwork”.
  5. Done!

This procedure allowed me to get an OS deployment done now, rather then spending hours loading drivers into our MS Deployment Workbench, rebuilding media, and testing, testing, testing.

Time Sync in MDT 2010/WinPE, take 3

Third time is the charm? I found after a few passes that the script I put together for syncing system clocks in Windows was not actually working the way that I thought it was. While the system date was getting set correctly, time consistently was off by three hours. WTF?!?!? The problem, as it turns out, is not in coding errors, but rather in a misunderstanding of WinPE system time.

WinPE, as you may know, has no control panels. It has no “Windows Time” service. It has no time service management utilities such as “w32tm.exe”. So since it has no way to display its time zone settings, does that mean that it is not Time Zone aware? The answer is no.

WinPE has a default timezone of PST (GMT-8). This can be changed using the DISM utility, but sadly setting the default timezone for your LiteTouch/MDT boot images is not an option that is exposed in the Deployment Workbench. You would have to update the source winpe.wim image in the Windows AIK “tools\petools” directory it change the default for all future workbench-generated boot images. Rather than do this, and risk forgetting to do it again for all future AIK updates, I decided to set the timezone in my LiteTouch task sequences. It is pretty easy, requiring one additional custom command line in the task sequence:

reg.exe import "%SCRIPTROOT%\EST_tz.reg"

The “reg” file referenced here is simply an export of HKLM\System\CurrentControlSet\Control\TimeZoneInformation, from a system in the correct local timezone.

I then updated the WinPE timesync script to sync directly against our deployment server using “net time /set /y”, since this seems like the most reliable tool in WinPE:

Option Explicit
RunNewInstance

'//—————————————————————————-
'//  Global Constants
'//—————————————————————————-

'const DEPLOY_SERVER = "\\sysimg3.campus.ad.uvm.edu"

'//—————————————————————————-
'//  Main Class
'//—————————————————————————-

Class ZUVMsetTimePE

    '//—————————————————————————-
    '//  Global constant and variable declarations
    '//—————————————————————————-

    Dim iRetVal

    '//—————————————————————————-
    '//  Constructor to initialize needed global objects
    '//—————————————————————————-

    Private Sub Class_Initialize

    End Sub
    '//—————————————————————————-
    '//  Main routine
    '//—————————————————————————-

    Function Main
	
		' setTimePE.vbs
		' J. Greg Mackinnon, 2010-10-12
		' Sets time from within a WinPE 3.0 environment.
		' ASSUMES:  Local timezone is set correctly in the WinPE system registry.
		' ASSUMES:  Time on the deployment server is set correctly.

		' Declare objects and variants
		Dim oExec
		Dim sDPServ
		
		' Initiate variants
		sDPServ = oEnvironment.Item("SMSDP")

		' Procedure: Display current time:
		oLogging.CreateEntry "setTime> " & "Current Time is: " & Date & " " & Time, LogTypeInfo
		
		' Procedure: Set local time against time on deployment server:
		oLogging.CreateEntry "setTime> About to run command: " & "net.exe time \\" & sDPServ & " /set /y", LogTypeInfo
		set oExec = oShell.Exec("net.exe time \\" & sDPServ & " /set /y")
		Do While oExec.Status = 0
			 WScript.Sleep 100
		Loop
		do while not oExec.StdOut.AtEndOfStream
			oLogging.CreateEntry "setTime> " & oExec.StdOut.ReadLine, LogTypeInfo
		loop
		oLogging.CreateEntry "setTime> " & "Current Time is now: " & Date & " " & Time, LogTypeInfo

	End Function

End Class

   

Adding Drivers to the built-in Windows Recovery Environment

Windows 7 and Windows 2008 R2 feature an out-of-box installation of the very useful Windows Recovery Environment (WinRE).  WinRE can save your buttocks… but what if your system is using storage drivers that are not available in the out-of-box WinRE environment?  Such as the VMware Paravirtual SCSI driver (PVSCSI)?

Fortunately, WinRE is just a modified WinPE image, so you can add drivers using DISM.exe, right?  Sure… if you can find the WinPE image that is used by WinRE!  Fortunately, there is a tool for this.

Open a command prompt on your Server 2008 R2 system, and run “REAgentC.exe /info”… the output will tell you where to find the image:

Recovery Environment: \\?\GLOBALROOT\device\harddisk0\partition2\Recovery\bb338b68-0d2c-11df-be64-84e1223bd0bb
BCD Id: bb338b68-0d2c-11df-be64-84e1223bd0bb

So, on the second partition of the first disk (also known as the “C:” drive, according to “Diskpart”), you will find a hidden “recovery” directory, with subdirectory “bb338b68-0d2c-11df-be64-84e1223bd0bb”.  Within here is “winre.wim”.

Now there is simply the matter of injecting the drivers. First, place all the drivers you wish to inject into an easily accessible directory (such as c:\local\temp, in our example), and then run the following commands:

1
2
3
4
5
mkdir c:\wimtemp
dism /mount-wim /WimFile:c:\recovery\bb338b68-0d2c-11df-be64-84e1223bd0bb\winre.wim /index:1 /mountdir:c:\wimtemp
dism /image:c:\wimtemp /add-driver /driver:C:\local\temp /recurse
dism /unmount-wim /mountdir:c:\wimtemp /commit
rmdir /q c:\wimtemp

Et voila! We press “f8″ on next reboot, select the recovery environment, and suddenly we have full access to the local disk.