Categories
OS Deployment

Adding Microsoft Windows Deployments

This article assumes that you have already read and completed the instructions from my previous PXE-related posts. You might want to read them first.

Of all of the network boot stuff I’ve done, setting up Windows PE to PXE boot using non-Microsoft solutions was by far the most challenging. Most of the instructions I found online were either incomplete, or too specific to the user’s setup to be of much use. After a lot of trial and error (and much swearing), I finally have everything working the way it’s supposed to – although it’s a far cry away from being as flexible as I’d like.

You can find the files required to get Windows PE to PXE boot in winpe.wim included with the Windows Automated Installation Kit 2.0 (WAIK 2.0). You’ll also want to install the Microsoft Deployment Toolkit and all of its dependencies somewhere (preferably a Windows Server 2003 SP2 system, but it should run fine on XP or later). Luckily, WAIK is a dependency of MDT, so if you’re installing MDT somewhere, then you’ll also have a copy of WAIK 2.0.MDT 2008 allows you to completely automate, audit, and simplify installing Windows XP, Windows Server 2003 (including R2), Windows Server 2008, and Windows Vista.

Putting the Files in Place

  • create /var/lib/tftpboot/winpe on your TFTP server
  • on the system with WAIK installed (likely the same server as MDT 2008), open the Windows PE Tools Command Prompt and run the following commands:
    mkdir C:\mount
    imagex /mount "C:\Program Files\Windows AIK\Tools\PETools\x86\winpe.wim" 1 c:\mount
    
  • copy everything in c:\mount\Windows\Boot\PXE\ to your TFTP server’s /var/lib/tftpboot/winpe/ folder
  • unmount the winpe.wim:
    imagex /unmount c:\mount
  • ensure that all files/directories in /var/lib/tftpboot/winpe/ are lower-case:
    find /var/lib/tftpboot/winpe/ -type d -o -type f -exec mv {} `echo {} | tr [:upper:] [:lower:]` \;
  • copy the following batch file to ANY system running Windows Vista or Windows Server 2008, run it, and copy c:\myBCD to /var/lib/tftpboot/winpe/bcd:
    REM
    REM Where should I write the new BCD? Note that you do NOT want to use c:BCD on a system
    REM running Windows Vista or 2008 Server, as the changes you make will OVERWRITE the running
    REM system's boot configuration!
    REM
    set BCD=c:\myBCD
    
    REM
    REM What should I display in the Windows PE boot menu for this WIM?
    REM
    set TITLE="First Boot Menu Entry"
    
    REM
    REM Where are the Windows PE boot files located? Note that this is relative to your
    REM TFTP server's root directory, and should be specified using Windows' path separator
    REM (i.e. '\', and not '/'), with no trailing backslash!
    REM
    set TFTPPATH=winpe
    
    REM
    REM What's the filename of the WIM on the TFTP server?
    REM
    set WIM=%TFTPPATH%\winpe.wim
    
    REM
    REM How long to wait before booting the default entry, in seconds?
    REM
    set TIMEOUT=5
    
    REM Create the BCD store (which WIPES ANY EXISTING CONFIGURATION FROM THE FILE SPECIFIED!)
    bcdedit -createstore %BCD%
    
    REM Since we're booting from the network, we want to load the image into RAM:
    bcdedit -store %BCD% -create {ramdiskoptions} /d "Ramdisk options"
    bcdedit -store %BCD% -set {ramdiskoptions} ramdisksdidevice  %TFTPPATH%
    bcdedit -store %BCD% -set {ramdiskoptions} ramdisksdipath %TFTPPATH%\boot.sdi
    
    REM This line actually creates the menu entry. Note that it returns a GUID that needs
    REM to be used in the commands that follow. I stole the "for /f..." bit from a co-worker
    REM but I haven't tested it myself to ensure that it works... YMMV.
    for /f "tokens=3" %i in ('bcdedit -store %BCD% -create /d "%TITLE%" /application osloader') do set GUID=%i
    
    REM Change the options for our new menu entry. The first 3 never change:
    bcdedit -store %BCD% -set %GUID% systemroot \windows
    bcdedit -store %BCD% -set %GUID% detecthal Yes
    bcdedit -store %BCD% -set %GUID% winpe Yes
    
    REM ...the next two will depend on the WIM you're using:
    bcdedit -store %BCD% -set %GUID% osdevice ramdisk=[boot]%WIM%,{ramdiskoptions}
    bcdedit -store %BCD% -set %GUID% device ramdisk=[boot]%WIM%,{ramdiskoptions}
    
    REM And finally we create the actual boot manager portion of the BCD:
    bcdedit -store %BCD% -create {bootmgr} /d "WinPE BootMgr"
    bcdedit -store %BCD% -set {bootmgr} timeout %TIMEOUT%
    
    REM ...and change the order menu entries are displayed in. Note that the WAIK documentation
    REM incorrectly specifies this command as bcdedit -store %BCD% -set displayorder %GUID%.
    bcdedit -store %BCD% -displayorder %GUID%
    
  • install, configure, and run the Microsoft Deployment Toolkit to the point where it is creating <distribution share>\Boot\LiteTouch_<arch>.wim (the stock configuration of MDT should produce this file for you, once you’ve satisfied all of the dependencies MDT has)
  • copy <distribution share>\Boot\LiteTouch_x86.wim to /var/lib/tftpboot/winpe/winpe.wim

Configuring PXELinux/TFTP-HPA to Boot Windows PE

  • Add a boot label to /var/lib/tftpboot/pxelinux.cfg/default, so that it contains the following:
    label windows
      menu label ^Microsoft Windows
      TEXT HELP
        Installs Microsoft Windows XP, 2003, Vista, or 2008 after answering only a few questions.
      ENDTEXT
      kernel winpe/pxeboot.0
    
  • edit /var/lib/tftpboot/pxelinux.cfg/remap so that the following lines come AFTER any existing rules:
    re ^pxeboot.n12 winpe/pxeboot.n12
    re ^pxeboot.com winpe/pxeboot.com
    re ^pxeboot.0 winpe/pxeboot.n12
    re ^bootmgr.exe winpe/bootmgr.exe
    r ^\Boot\ winpe/
    r ^\boot\ winpe/

Remap Rules Explained

  • re ^pxeboot.n12 winpe/pxeboot.n12: requests for pxeboot.n12 in the root folder returns winpe/pxeboot.n12 (a file which actually exists)
  • re ^pxeboot.com winpe/pxeboot.com: requests for pxeboot.com in the root folder returns winpe/pxeboot.com
  • re ^pxeboot.0 winpe/pxeboot.n12: pxeboot (the network bootstrap program from Windows PE) comes in two flavours: .com and .n12. The .com version prompts the user to press F12 if they want to boot from the network, whereas the .n12 version does not prompt. This line maps any request for pxeboot.0 (which we use in our PXELinux configuration file) to winpe/pxeboot.n12, so the user isn’t prompted to boot from the network a second time (the first time, the user selected our WinPE option from the PXELinux menu…)
  • re ^bootmgr.exe winpe/bootmgr.exe: fixes requests for bootmgr.exe, which is assumed to be in the root directory of your TFTP server, even when it isn’t…
  • r ^\Boot\ winpe/: remaps any request starting with “Boot” to “winpe/”
  • r ^\boot\ winpe/: remaps any request starting with “boot” to “winpe/”

Putting it All Together

At this point, you should be able to use your PXE client to boot into Windows PE, and install Microsoft Windows using the LiteTouch method provided by the Microsoft Deployment Toolkit.

Random Notes, Limitations, and Gotchas

  • only a single BCD can be used
  • the BCD can reference multiple WIMs, but there’s no way (that I know of) to auto-select a WIM, so the user must choose one (this would be useful if, e.g. the system could auto-detect x86 vs. x64 systems, and load up the appropriate WIM)
  • pxeboot.com (one part of the bootstrap for Windows PE) has behaviour/paths hard-coded in it, so if you run into problems booting PE, you MUST pay attention to the full path and filename requested by your PXE client. More often than not, problems here can be fixed using either symlinks or /var/lib/tftpboot/pxelinux.cfg/remap to redirect to the correct file
  • pxeboot.com MUST be renamed to pxeboot.0 (the .com extension is handled differently by PXELinux, and will not work otherwise). You’ll also need an entry in /var/lib/tftpboot/pxelinux.cfg/remap to redirect to the correct file once it’s renamed, as you won’t be able to modify the bootstrap application(s)
  • you cannot use PXELinux’s Alternate TFTP Server functionality (e.g. point to a file on another TFTP server rather than loading a local file) to boot Windows PE from a secondary TFTP server, as bootmgr.exe & pxeboot.com examine the DHCP response to determine the TFTP server name – regardless of what PXELinux says – and will likely fail to load the correct file. I experimented with this for over a week to try and figure out a way to get multiple BCDs and/or architecture auto-selection working, before I finally gave up on this approach.