Windows Deployment Services (WDS) is a set of services and APIs to facilitate Windows operating system installation by using PXE, DHCP and TFTP to bootstrap WinPE, the Windows Preinstallation Environment. You can think of it as providing similar functionality to iPXE with server-side scripting, where clients are served boot configuration and images based on various criteria, such as hardware architecture.
This appnote is about chainloading WDS from iPXE in a straight-forward manner.
The WDS TFTP service relies on a registry key
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/WDSServer/Providers/WDSTFTP/ReadFilter
that controls which TFTP paths are mapped to the directory containing
the various installation files defined by the RootFolder
registry key in the same location.
Depending on the existing configuration, it is likely that additional patterns must be added to make iPXE and the WDS boot programs work correctly.
Make sure the following patterns are included in the ReadFilter
list:
boot/*
boot\*
/boot/*
\boot\*
/boot\*
This allows all relavant combinations of forward and backward slashes, with or without a prefix slash. The last entry is particularly odd, but is actually used by the initial WDS network boot program once it has been chainloaded by iPXE, as seen in the example below.
After changing the ReadFilter
list, reload the TFTP service to
ensure it accepts the full list of patterns.
Loading the initial WDS network boot program wdsnbp.com
can be
done either directly from the iPXE shell or via a menu entry. The only
thing that needs to be modified is the DHCP next-server
parameter,
which will let wdsnbp.com
know which server to communicate with.
Be sure to set DHCP options so that they are
made available to the PXE NBP. For example, the next-server
parameter can be set via netX/next-server
.
Example iPXE commands to chainload wdsnbp.com
:
set netX/next-server ip.of.wds.server imgexec tftp://${netX/next-server}/boot/x86/wdsnbp.com
Once wdsnbp.com
starts, it initiates a session with the WDS server
that was specified in the DHCP next-server
parameter. The session
protocol uses a combination of DHCP requests and responses and TFTP to
provide the client with the appropriate boot loader (such as
bootmgr.exe
or bootmgfw.efi
) and boot configuration data
(BCD).
The wdsnbp.com
program performs client architecture detection and
reports it back to the server via the WDS session. This session
protocol uses DHCP as an RPC service endpoint, and the data passed
back and forth (such as architecture information) is encoded in DHCP
option 250. Together with option 252 (used by WDS to indicate BCD file
name) and the DHCP file
field (pointing the client to the next
network boot program), the DHCP+TFTP negotiation completes the WDS
session.
/boot/x86/wdsnbp.com
from ip.of.wds.server
.wdsnbp.com
uses a direct DHCP request to ip.of.wds.server
, with no option 250 nor 252 defined.boot\x86\wdsnbp.com
0b0101100400000001ff
\Tmp\x86{<GUID>}.bcd
wdsnbp.com
uses a direct DHCP request to ip.of.wds.server
:0d0208000e010001020006ff
boot\x86\wdsnbp.com
0b0101100400000001ff
\Tmp\x86x64{GUID}.bcd
wdsnbp.com
requests TFTP /boot\x86\wdsnbp.com
from ip.of.wds.server
. Note the use of slashes.wdsnbp.com
uses a direct DHCP request to ip.of.wds.server
:0c01010d0208000e010001020006ff
boot\x64\pxeboot.n12
.0b0101100400000001ff
\Tmp\x86x64{GUID}.bcd
wdsnbp.com
requests TFTP /boot\x64\pxeboot.n12
.pxeboot
requests TFTP /boot\x64\bootmgr.exe
.pxeboot
requests TFTP \Tmp\x86x64{GUID}.bcd
.bootmgr.exe
executes and reads the BCD.
Due to the poor error reporting in the WDS boot programs, the go-to
troubleshooting tool should be a network packet analyzer like
Wireshark. Packets can be dumped using
other tools like tcpdump
or tshark
before being loaded into
Wireshark for analysis.
Here's a Wireshark filter that shows only DHCP and useful TFTP packets by omitting TFTP opcode 3 (data packet) and 4 (acknowledgement):
bootp || !(tftp.opcode==3 || tftp.opcode==4)
Things to pay particular attention to:
Ensure that the DHCP next-server
parameter is specified correctly
in the iPXE commands. If it is not configured correctly, it should be
evident from the network capture that either the first DHCP or TFTP
request from wdsnbp.com
is directed towards the wrong IP.
Make sure the WDS TFTP server's read filter has mapped the relevant
path names. Inspect the use of slashes in the DHCP packets to see how
they are used, and check that the ReadFilter
registry setting is
configured appropriately.
If either wdsnbp.com
or pxeboot.n12
gets stuck in a request
loop, it is likely that the initial TFTP download worked, but
subsequent ones are failing. This can happen because iPXE uses forward
slashes in the TFTP file path, while the WDS boot programs are prone
to using a mix of forward and backward slashes.
Make sure the WDS TFTP server's read filter has mapped the relevant
path names. Inspect the use of slashes in the DHCP packets to see how
they are used, and check that the ReadFilter
registry setting is
configured appropriately.
The upside of chainloading WDS from iPXE is that it provides a fully working and isolated WDS setup, while iPXE remains in control as the initial boot program with WDS supplied as just another choice amongst the variety of alternate boot options. WDS remains in full control of its own configuration.
A drawback with WDS is that it uses TFTP (although with extensions that allow larger receive windows), which is not nearly as fast as HTTP, especially if there is more than a few ms round-trip time between the client and server. This results in somewhat long loading times for large WIM images, particularly on links with medium to high latency.
A good alternative to the PXE mechanism of WDS is wimboot, a boot loader that takes
over the roles of wdsnbp.com
and pxeboot.n12
. It lets you
fetch all the relevant files over HTTP and hand over execution to
bootmgr.exe
. There is a drawback, however: Control over the
dynamic BCD boot menu is taken away from WDS, as a static BCD file is
served instead.