January 6, 2010

Build a Windows 7 PE boot CD with defrag

If you deploy virtual machines from templates using the standard vSphere tools, you know how valuable it is to get your templates as small as possible. A handy trick I learned a while back is to use vCenter Converter to import a virtual machine that I'm working up to be a template, and choose to resize the disk to the minimum size. The process is pretty simple: configure the system as though it were going to be deployed as an image, remove every temp file and hotfix uninstall folder, run sysprep and power down, boot up from an .iso of a rescue boot disk with a defrag utility, delete the pagefile.sys file, run a defrag, power down again, and use vCenter Converter to import the powered off virtual machine as a new machine and shrink the virtual hard disk during the process. Using this procedure, I've gotten a Windows XP template down from a 5.27 GB minimum size in vCenter Converter, to 3.08 GB. That's an almost 42% reduction in size, and is a huge time saver when deploying new systems.

In the past I have used a customized BartPE boot disk for this, but I wanted a more lightweight solution that booted up faster and only had the tools needed for the specific job. Windows PE fit the bill, but doesn't include defrag.exe by default. There are some tutorials out there on how to get defrag working in the Vista version of Windows PE, but I don't have any Vista installs around, and would like to keep it that way. So I dug around for a bit, and was able to get defrag working in the Windows 7 version of PE.

Windows AIK
First thing, you need to download a copy of the Windows Automated Installation Kit (just google Windows AIK). There are three versions of the AIK now, and the latest one supports Windows 7, so make sure you download the Windows 7 version.

  • Insert the AIK DVD you created and open startcd.exe if the main menu screen doesn't open automatically. Choose Windows AIK Setup from the menu.

  • It's your standard install process, click through the defaults and when it's finished you'll find a Microsoft Windows AIK folder has been created in the Start menu.

  • Open the Deployment Tools Command Prompt from the Microsoft Windows AIK menu, which will bring up a command prompt with the AIK executables added to the PATH environment variable.

  • In the command prompt, type the following, using C:\PEBuild or another folder name for your build folder. The command expects to create the build folder, and will fail if the folder already exists:

    copype.cmd x86 c:\PEBuild

    The copype.cmd script copies the files and directories needed to build a PE boot disk for a specific architecture, which is x86 here. Note that the script also changes the working directory to the path we specified for the build files. Make sure you stay in this path for the following commands.

  • Now we'll use the ImageX tool to mount the default Windows PE image that ships with AIK in read/write mode on the local filesystem. By mounting the image, we'll be able to add some files to it:

    imagex.exe /mountrw winpe.wim 1 mount

  • This next command copies the ImageX deployment tools to the PE boot disk, allowing you to capture an image of a hard disk in ImageX format. This isn't really relevant to this project, but we may as well add them in case we want to use them later:

    xcopy "C:\Program Files\Windows AIK\Tools\x86\*.*" mount\ /s

  • Here comes the customization part, and we'll need two files from a running Windows 7 workstation. The commands we've used so far will produce a 32-bit Windows PE image, so be sure the Windows 7 system you copy the files from is also 32-bit. My first attempt at this was on my 64-bit workstation, and when I tried to use the defrag utility from within Windows PE, I got a message that it wasn't compatible with the version of Windows I was using.

    From the 32-bit Windows 7 workstation, copy:


    - and -


  • Now unmount the build image with another ImageX command, but make sure you don't have any Windows Explorer windows or the command prompt open to the mount folder first:

    imagex.exe /unmount mount /commit

  • If you type a dir command, you'll see the modified winpe.wim image file in the C:\PEBuild folder. We need to copy this to a specific folder and file name for the next few AIK commands to work:

    copy /y winpe.wim ISO\sources\boot.wim

  • This command will create the PE .iso file in the c:\PEBuild folder, naming it pe-defrag.iso, so modify for your build path and desired file name. This is a long command, so make sure you get the whole line if copying it by double clicking in the grey box:

    oscdimg.exe -n -b"C:\Program Files\Windows AIK\Tools\PETools\x86\boot\etfsboot.com" C:\PEBuild\ISO C:\PEBuild\pe-defrag.iso

Boot it
Now you can either copy the .iso file over to an ESX server and VMFS LUN, or use the local vSphere client to attach the .iso to a VM. Boot up a test VM with the PE .iso. After a minute or so, you'll find the VM has booted up to a command prompt, with a grey, Vista'ish background. Pretty boring, but a command prompt is all we need for the next few steps.

  • In the command prompt, change the working directory to the (hopefully) offline mounted NTFS volume that holds the operating system files for the template:


  • Since the pagefile.sys file is hidden, enter a dir command that shows hidden files:

    dir /a:h

  • Remove the pagefile.sys file, and notice that the del command also needs to have hidden files specified:

    del /a:h pagefile.sys

  • Now defrag the volume, forcing it to defrag all files (-w) and print verbose output (-v):

    defrag c: -w -v

  • You can exit PE with an exit command, but that reboots the VM, which has ruined a few sysprepped images when I forgot to interrupt the boot. So now I use the shutdown command to force it to shut down:
    C:\WINDOWS\system32\shutdown /s

    The shutdown command can take a few seconds to actually power down the VM, so be patient.

Seal, shrink, deploy
You'll want to run the defrag on a template that's been sealed up with sysprep. After deploying one of these shrunken templates, you'll need to edit the virtual hard disk before the first power on and expand it to a reasonable size. Windows will automatically expand the operating system partition during the first boot if you include the command ExtendOemPartition=1 in the [Unattended] section of the sysprep.inf file for a Windows XP/2003 image, or ExtendOSPartition=true in the Unattend.xml file for a Vista/Windows 7 image.

If you deploy templates in VMware Workstation, you'll find that you aren't allowed to just simply edit the virtual hard disk and expand it. For deployments in Workstation, you'll need to use the C:\Program Files\VMware\VMware Workstation\vmware-vdiskmanager.exe utility to expand the .vmdk before the first boot.