In this posting I’m creating Windows 7 pre-installation (Windows PE) and rescue images that can be PXE booted for both 64-bit and 32-bit systems. As source I’m using Windows 7 Ultimate retail images. You need a machine running Windows 7 to build the images using Windows Automated Installation Kit. This machine is named “Technician Computer” in the documentation[1]. The resulting bootable images are stored on a Linux server that has a DHCP server and TFTP server configured to serve PXE clients. ISC DHCP Server 3.1.2 and tftpd-hpa 0.49 are used. On the server TFTP root is /var/lib/tftpboot and we want to make Windows stuff available via TFTP under the path /i386/windows/. DHCP server is passing the following DHCP option to PXE clients:

    filename "/i386/pxelinux.0";

This PXELinux kernel comes from syslinux 3.63.

Other people have been writing about this stuff, too[2],[3],[4].

Windows Automated Installation Kit

  1. Download and install WAIK for Windows 7[5] on the Technician Computer.

  2. Start Deployment Tools Command Prompt as Administrator. All subsequent commands are typed in the command prompt.

Create Windows PE images

The following steps show you all the commands that are required to create and configure PXE bootable Windows PE 64-bit and 32-bit images.

  1. Insert your Windows 7 Ultimate 64-bit DVD to your DVD drive, mount an ISO image of the retail DVD or otherwise have the content of the retail DVD available under some directory. In this guide we’ll use DVD as the source and the content of the media is available under g:\.

  2. Create Windows PE 64-bit working directory

    copype.cmd amd64 c:\winpe_x64
  3. The plain Windows PE image created by WAIK for Windows 7 above doesn’t contain The Windows Recovery Environment[6]. However, we can use the Windows RE image on the DVD[7] as basis for our custom image. This way we get the recovery features and tools. So let’s mount the install image from the DVD and copy Windows RE image as our base image.

    md c:\winpe_x64\os_install
    imagex /mount g:\sources\install.wim 1 c:\winpe_x64\os_install
    copy c:\winpe_x64\os_install\windows\system32\recovery\winre.wim c:\winpe_x64\winpe.wim
    imagex /unmount c:\winpe_x64\os_install
    rd c:\winpe_x64\os_install
  4. You can now eject the DVD

  5. Mount the Windows PE 64-bit image

    imagex /mountrw c:\winpe_x64\winpe.wim 1 c:\winpe_x64\mount
  6. You can install 3rd party drivers to the Windows PE environment[8] if you need. I’m going to install some VMWare drivers here[9]. VMware drivers were copied from a host running under VMWare with VMWare Tools installed. Drivers are available at c:\Program Files\VMWare\VMWare Tools\Drivers\ and were copied to c:\winpe_x64\drivers\vmware.

    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\audio\vmaudio.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\mouse\vmmouse.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\pvscsi\pvscsi.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\vmxnet3\vmxnet3ndis6.inf
  7. Alternatively, you could add all the drivers under c:\winpe_x64\drivers\ in one go like this.

    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers /recurse
  8. You can see what drivers have been installed with the command

    dism /image:c:\winpe_x64\mount /get-drivers
  9. If you wish, you might set internationaliztion and localization options in the Windows PE environment[10]. In this example Finnish settings are used for standards and formats, keyboard layout and timezone while all other settings are set to American English by default.

    dism /image:c:\winpe_x64\mount /set-allintl:en-us
    dism /image:c:\winpe_x64\mount /set-userlocale:fi-fi
    dism /image:c:\winpe_x64\mount /set-inputlocale:fi-fi
    dism /image:c:\winpe_x64\mount /set-timezone:"FLE Standard Time"
  10. You may verify internationalization and localization settings by running the following command.

    dism /image:c:\winpe_x64\mount /get-intl
  11. If you don’t want to start the Windows Recovery Environment by default, edit c:\winpe_x64\mount\windows\system32\winpeshl.ini and replace the program that is launched by the Windows PE shell[11]. I use the following winpeshl.ini to initialize some stuff using wpeinit.exe[12] and the launch the command prompt. When your image is ready and you can boot it, you can launch The Windows Recovery Environment by running %SYSTEMDRIVE%\sources\recovery\recenv.exe from the command prompt after booting Windows PE.

  12. Install ImageX[13] tool from Windows AIK installation to the Windows PE environment. This allows you to work with the Windows Imaging File Format WIM[14] images within the Windows PE environment. You could use ImageX to install Windows 7 locally on a system supporting PXE booting using an installation image stored on a network share[15], for instance.

    copy "c:\Program Files\Windows AIK\Tools\amd64\imagex.exe" c:\winpe_x64\mount\Windows\system32
  13. Install any 3rd party applications and scripts you may want. Just copy the stuff somewhere under the image mount point, e.g. self-contained executables could go to c:\winpe_x64\mount\Windows\system32. Some examples include

    • Explorer++[16]
      • File manager
    • PE Network Configurator[17]
      • Allows you to configure networking in Windows PE
  14. Copy all files (but the directories containing localization data are not needed) from c:\winpe_x64\mount\Windows\Boot\PXE\ to /var/lib/tftpboot/i386/windows on the TFTP server.

  15. Unmount Windows PE 64-bit image

    imagex /unmount /commit c:\winpe_x64\mount
  16. Create Windows PE 32-bit environment. Windows 7 Ultimate 32-bit installation media must be available at g:\ so insert the DVD or mount the image first. I’ve included bulk of the commands here in one go, see the steps above for explanation.

    copype.cmd x86 c:\winpe_x86
    md c:\winpe_x86\os_install
    imagex /mount g:\sources\install.wim 1 c:\winpe_x86\os_install
    copy c:\winpe_x86\os_install\windows\system32\recovery\winre.wim c:\winpe_x86\winpe.wim
    imagex /unmount c:\winpe_x86\os_install
    rd c:\winpe_x86\os_install
    imagex /mountrw c:\winpe_x86\winpe.wim 1 c:\winpe_x86\mount
    dism /image:c:\winpe_x86\mount /add-driver:c:\winpe_x86\drivers /recurse
    dism /image:c:\winpe_x86\mount /set-allintl:en-us
    dism /image:c:\winpe_x86\mount /set-userlocale:fi-fi
    dism /image:c:\winpe_x86\mount /set-inputlocale:fi-fi
    dism /image:c:\winpe_x86\mount /set-timezone:"FLE Standard Time"
    copy "c:\Program Files\Windows AIK\Tools\x86\imagex.exe" c:\winpe_x86\mount\Windows\system32
  17. Install any 3rd party software or customizations (the winpeshl.ini customization shown above, for instance) for the Windows PE 32-bit environment in c:\winpe_x86\mount.

  18. Unmount Windows PE 32-bit image

    imagex /unmount /commit c:\winpe_x86\mount
  19. Your Windows PE images c:\winpe_x64\winpe.wim and c:\winpe_x86\winpe.wim are now ready for booting! Besides booting over PXE[18], you could create a bootable USB stick using these same images[19], for instance.

Boot configuration

  1. Create boot configuration data[20],[21] using the bcdedit tool[22].

    bcdedit /createstore c:\bcd-pxeboot
  2. Create ramdisk options in the boot configuration data

    bcdedit /store c:\bcd-pxeboot /create {ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {ramdiskoptions} ramdisksdidevice boot
    bcdedit /store c:\bcd-pxeboot /set {ramdiskoptions} ramdisksdipath \i386\windows\boot.sdi
  3. Create OS Loader settings for the Windows PE 64-bit image in the boot configuration data.

    bcdedit /store c:\bcd-pxeboot /create /application osloader /d "Windows PE 64-bit"
  4. Previous command will output a GUID for Windows PE 64-bit. In this guide we’ll use fa76e260-385f-11df-8c80-00241d86f38c, adjust to match yours.

    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} systemroot \Windows
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} detecthal Yes
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} winpe Yes
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} osdevice ramdisk=[boot]\i386\windows\boot_x64.wim,{ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} device ramdisk=[boot]\i386\windows\boot_x64.wim,{ramdiskoptions}
  5. Create OS Loader settings for the Windows PE 32-bit image in the boot configuration data.

    bcdedit /store c:\bcd-pxeboot /create /application osloader /d "Windows PE 32-bit"
  6. Previous command will output a GUID for Windows PE 32-bit. In this guide we’ll use 28318ca0-3860-11df-8c80-00241d86f38c, adjust to match yours.

    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} systemroot \Windows
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} detecthal Yes
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} winpe Yes
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} osdevice ramdisk=[boot]\i386\windows\boot_x86.wim,{ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} device ramdisk=[boot]\i386\windows\boot_x86.wim,{ramdiskoptions}
  7. Create Boot Manager settings in the boot configuration data. Boot Windows PE 64-bit by default.

    bcdedit /store c:\bcd-pxeboot /create {bootmgr}
    bcdedit /store c:\bcd-pxeboot /set {bootmgr} timeout 10
    bcdedit /store c:\bcd-pxeboot /displayorder {fa76e260-385f-11df-8c80-00241d86f38c} {28318ca0-3860-11df-8c80-00241d86f38c}
    bcdedit /store c:\bcd-pxeboot /default {fa76e260-385f-11df-8c80-00241d86f38c}

Copy files to the boot server

Note the casing of the target file names stored on the Linux server! It’s important to get these right, otherwise booting the client won’t work.

  1. Copy c:\winpe_x64\winpe.wim to the TFTP server as the file /var/lib/tftpboot/i386/windows/boot_x64.wim

  2. Copy c:\winpe_x86\winpe.wim to the TFTP server as the file /var/lib/tftpboot/i386/windows/boot_x86.wim

  3. Copy file c:\Program Files\Windows AIK\Tools\PETools\amd64\boot\boot.sdi to /var/lib/tftpboot/i386/windows on the TFTP server.

  4. Copy directory c:\Program Files\Windows AIK\Tools\PETools\amd64\boot\fonts as /var/lib/tftpboot/i386/windows/Fonts on the TFTP server.

  5. Copy the boot configuration data c:\bcd-pxeboot to the TFTP server as the file /var/lib/tftproot/i386/windows/BCD.

  6. Ensure that all files that were copied earlier from the mounted Windows PE 64-bit environment c:\winpe_x64\mount\Windows\Boot\PXE\ to /var/lib/tftpboot/i386/windows have lower case file names on the TFTP server.

Configure the boot server

  1. In order to configure PXELinux, Linux TFTP server and Windows PE network boot to work together, some tuning is required. On the server you must serve the Windows PXE boot kernel with suffix .0 or it won’t work[3]. Let’s create a symlink for that.

    ~: # ln -s pxeboot.n12 /var/lib/tftpboot/i386/windows/pxeboot.0
  2. Adjust your PXE configuration file (/var/lib/tftpboot/i386/pxelinux.cfg/default in my case) to boot /i386/windows/pxeboot.0 we just created. You could use e.g. the following PXE menu entry in /var/lib/tftpboot/i386/pxelinux.cfg/default:

    menu title Boot Menu
    label winpe
      menu label ^Windows PE
      kernel windows/pxeboot.0
  3. Configure TFTP server remapping. The Windows PE network boot system uses hard coded paths for some of the files it retrieves over TFTP. Those paths don’t match our setup here by default. It also uses backslashes instead of slashes to separate directories. This doesn’t work with TFTP server on Linux Fortunately, tftpd-hpa supports file remapping using an external configuration file[23]. Save the following text somewhere (/etc/tftpd-remap.conf for example) and adjust TFTP server startup so that this file is loaded with the tftpd -m command line option.

    # Map DOS style path separators to Unix path separators
    gr \\ /
    # Locate bootmgr.exe
    r ^bootmgr\.exe /i386/windows/bootmgr.exe
    # Map /Boot to /i386/windows
    r ^/Boot /i386/windows