====== Chainloading Windows Deployment Services ====== [[http://en.wikipedia.org/wiki/Windows_Deployment_Services|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 [[http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment|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. ===== Configure the WDS TFTP service ===== 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. {{ :appnote:regedit-wdstftp.png?400|RegEdit WDSTFTP}} 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. ===== Chainload wdsnbp.com ===== 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 [[:settings#pxe_nbps|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 ===== The WDS boot process ===== 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. ==== Example boot process ==== - Client: iPXE requests TFTP ''/boot/x86/wdsnbp.com'' from ''ip.of.wds.server''. - Client: ''wdsnbp.com'' uses a direct DHCP request to ''ip.of.wds.server'', with no option 250 nor 252 defined. - Server: DHCP response: * filename: ''boot\x86\wdsnbp.com'' * option 250: ''0b0101100400000001ff'' * option 252: ''\Tmp\x86{}.bcd'' - Client: ''wdsnbp.com'' uses a direct DHCP request to ''ip.of.wds.server'': * option 250: ''0d0208000e010001020006ff'' - Server: DHCP response: * filename: ''boot\x86\wdsnbp.com'' * option 250: ''0b0101100400000001ff'' * option 252: ''\Tmp\x86x64{GUID}.bcd'' - Client: ''wdsnbp.com'' requests TFTP ''/boot\x86\wdsnbp.com'' from ''ip.of.wds.server''. Note the use of slashes. - Client: ''wdsnbp.com'' uses a direct DHCP request to ''ip.of.wds.server'': * option 250: ''0c01010d0208000e010001020006ff'' - Server: DHCP response: * filename: ''boot\x64\pxeboot.n12''. * option 250: ''0b0101100400000001ff'' * option 252: ''\Tmp\x86x64{GUID}.bcd'' - Client: ''wdsnbp.com'' requests TFTP ''/boot\x64\pxeboot.n12''. - Client: ''pxeboot'' requests TFTP ''/boot\x64\bootmgr.exe''. - Client: ''pxeboot'' requests TFTP ''\Tmp\x86x64{GUID}.bcd''. - Client: ''bootmgr.exe'' executes and reads the BCD. ===== Troubleshooting ===== {{ :appnote:wireshark-wds.png?400|WDS in Wireshark}} Due to the poor error reporting in the WDS boot programs, the go-to troubleshooting tool should be a network packet analyzer like [[https://www.wireshark.org/|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: * The destination IP for TFTP and DHCP requests. * The TFTP request filename. * TFTP error codes from the WDS server. * DHCP options in the client requests and server responses. * The WDS event log in Windows. ==== TFTP download errors ==== 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. ==== TFTP loops ==== 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. ===== Alternatives ===== 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. ===== References ===== * Windows Deployment Services: http://msdn.microsoft.com/en-us/library/windows/desktop/dd379586 * Managing Network Boot Programs: http://technet.microsoft.com/en-us/library/cc732351 * How the Boot Configuration Data Store Works: http://technet.microsoft.com/en-us/library/cc770770 * iPXE [[:howto:winpe|WinPE howto]]