- Turn off DHCP on the host-only network adapter in Virtual Network Editor. It uses 192.168.254.0/24, but you can use whatever IP or network you prefer.
- Create a VM using mostly normal settings. Make the main network adapter have NAT or however you connect VMs to the internet, and then add a second network adapter on the host-only network.
- Set the NIC on the host only network to a static IP (no gateway, we will use the DC for routing. Don't do this in prod):
netsh int ip set address ethernet0 192.168.254.254 255.255.255.0
Install-WindowsFeature -Name AD-Domain-Services, DHCP, DNS -IncludeManagementTools
ipmo ADDSDeployment
Install-ADDSForest -DomainName "ad.lab.i.rm.vg" -InstallDNS -CreateDnsDelegation:$false -Force:$true
Restart-Coputer -Force
The computer will reboot and set up the domain controller. It would be advisable to snapshot or backup the VM at this time.
Then set up the DHCP server:
$DHCPServerIP = "192.168.254.254"
Add-DhcpServerInDC -DnsName localhost -IPAddress $DHCPServerIP
Add-DhcpServerv4Scope -Name "Scope1" -StartRange "192.168.254.100" -EndRange "192.168.254.200" -SubnetMask "255.255.255.0" -State Active
Set-DhcpServerv4Binding -InterfaceAlias "Ethernet0" -BindingState $true
Set-DhcpServerv4OptionValue -ScopeId $DHCPServerIP -Router "192.168.254.254"
Set-DhcpServerv4OptionValue -ScopeId $DHCPServerIP -DnsServer "192.168.254.254"
Setup WDS:
mkdir C:\RemoteInstall
$WDSPath = "C:\RemoteInstall"
Install-WindowsFeature -Name WDS,WDS-Deployment,WDS-Transport -IncludeManagementTools
ipmo WDS
wdsutil /Initialize-Server /Server:$env:COMPUTERNAME /reminst:C:\RemoteInstall
copy D:\sources\boot.wim C:\boot.wim
Import-WdsBootImage -Path C:\boot.wim -NewImageName "Win2022 Boot Wim"
wdsutil /Set-Server /AnswerClients:all
#Set-WdsServer -NewClientApprovalPolicy AutoApprove
Set-DhcpServerv4OptionValue -ScopeId "192.168.254.0" -OptionId 66 -Value "192.168.254.254"
Add-DhcpServerv4Class -Name "PXEClient (UEFI x64)" -Type Vendor -Data "PXEClient:Arch:00007"
#Add-DhcpServerv4Class -Name "PXEClient (UEFI x64) 8" -Type Vendor -Data "PXEClient:Arch:00008"
#Add-DhcpServerv4Class -Name "PXEClient (UEFI x64) 9" -Type Vendor -Data "PXEClient:Arch:00009"
Add-DhcpServerv4Class -Name "PXEClient (UEFI x86)" -Type Vendor -Data "PXEClient:Arch:00006"
#Add-DhcpServerv4Class -Name "PXEClient (UEFI x86) 2" -Type Vendor -Data "PXEClient:Arch:00002"
Add-DhcpServerv4Class -Name "PXEClient (BIOS x86 & x64)" -Type Vendor -Data "PXEClient:Arch:00000"
Add-DhcpServerv4Policy -Name "PXEClient (UEFI x64)" -ScopeId 192.168.254.0 -Condition OR -VendorClass EQ,"PXEClient (UEFI x64)*"
Add-DhcpServerv4Policy -Name "PXEClient (UEFI x86)" -ScopeId 192.168.254.0 -Condition OR -VendorClass EQ,"PXEClient (UEFI x86)*"
Add-DhcpServerv4Policy -Name "PXEClient (BIOS x86 & x64)" -ScopeId 192.168.254.0 -Condition OR -VendorClass EQ,"PXEClient (BIOS x86 & x64)*"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x64)" -OptionId 067 -Value "boot\x64\wdsmgfw.efi"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x86)" -OptionId 067 -Value "boot\x86\wdsmgfw.efi"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (BIOS x86 & x64)" -OptionId 067 -Value "boot\x64\wdsnbp.com"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x64)" -OptionId 066 -Value "192.168.254.254"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x86)" -OptionId 066 -Value "192.168.254.254"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (BIOS x86 & x64)" -OptionId 066 -Value "192.168.254.254"
copy C:\Windows\System32\RemInst\boot\x64\wdsmgfw.efi C:\RemoteInstall\boot\x64\wdsmgfw.efi
Add-DhcpServerv4Class -Name "iPXE" -Type User -Data "iPXE"
Add-DhcpServerv4Policy -Name "PXEClient (UEFI x64) iPXE" -ScopeId 192.168.254.0 -Condition And -UserClass EQ,"iPXE"
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x64) iPXE" -OptionId 067 -Value "boot\iPXE\iPXE.conf"
The WDS server now works.
- Copy the ipxe.zip files to
C:\Remoteinstall\boot\
(this includes wimboot.x86_64.efi, x64\snponly_x64.efi, x64\snponly_usb_x64.efi, 2PXE\Boot, 2PXE\File\logo) - You need to open the WDS MMC, go to Properties (for the server) > "Boot" tab > Always continue the PXE boot (for both known and unknown clients).
- Remove Option 60 from the DHCP server, this causes WDS to hijack the DHCP requests.
Set Booting to iPXE:
Set-DhcpServerv4OptionValue -ScopeId 192.168.254.0 -PolicyName "PXEClient (UEFI x64)" -OptionId 067 -Value "boot\x64\snponly_x64.efi"
The iPXE needs internet access, so you need to create a NAT gateway
New-NetNat -Name "Nat1" -InternalIPInterfaceAddressPrefix "192.168.254.0/24"
mkdir C:\RemoteInstall\Boot\iPXE\
Create an iPXE menu in REMINST\Boot\iPXE\iPXE.conf
(notepad C:\RemoteInstall\Boot\iPXE\iPXE.conf
) containing:
#!ipxe
chain --autofree Boot\iPXE\boot.ipxe.conf
Download Nginx to set up as a web server. In the config file server section, change:
- listen to 8050 (or another port)
- in the
location /
section, changeroot
toC:\RemoteInstall\Boot
(the root of TFTP server) - add a line
error_page 405 =200 $uri;
- this line allows a POST for a static file.
- for debugging, add
autoindex on;
tolocation /
section. - Remember to unblock the port in Windows Firewall.
Set DHCP option 175 (custom string) to refer to the HTTP URL for additional files, for example "http://192.168.254.254:8050/". (Note you must append the /
)
Add-DhcpServerv4OptionDefinition -OptionId 175 -Name "ipxeUrl" -Type String -Description "iPxe HTTP URL"
Set-DhcpServerv4OptionValue -ScopeId "192.168.254.0" -OptionId 175 -Value "http://192.168.254.254:8050/"
Edit the boot config file to refer to the items that need boot. In this case, the boot config looks for the Windows boot image on our DC, and the Linux images on the internet. The ubuntu image is not working.
To add the RHEL files:
- make a directory at
C:\RemoteInstall\boot\rhel
- Copy
rhel-9.4-x86_64-dvd.iso\EFI\BOOT\BOOTX64.EFI
from the RHEL DVD. - Copy the kernel (vmlinuz) and initrd.img from the
rhel-9.4-x86_64-dvd.iso\images\pxeboot\
directory on the RHEL DVD.
#!ipxe
# Some menu defaults
set menu-timeout 60000
set submenu-timeout ${menu-timeout}
isset ${menu-default} || set menu-default exit
###################### MAIN MENU ####################################
:start
menu iPXE boot menu for Example Ltd
item --gap -- ----------------------- Glazier Images (Blank) --------------------------
item --key b windows-blank Windows (supports secure boot)
item --key q netboot NetbootXyz
item rhel9 Red Hat Enterprise Linux 9 (supports secure boot)
item debian Debian
item fedora Fedora
item shell Drop to iPXE shell
item reboot Reboot computer
item
item --key x exit Exit iPXE and continue BIOS boot
choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
set menu-timeout 0
goto ${selected}
:cancel
echo You cancelled the menu, dropping you to a shell
:shell
echo Type 'exit' to get the back to the menu
shell
set menu-timeout 0
goto start
:failed
echo Booting failed, dropping to shell
goto shell
:reboot
reboot
:exit
exit
############ MAIN MENU ITEMS ############
:windows-blank
kernel http://192.168.254.254:8050/wimboot.x86_64.efi
initrd http://192.168.254.254:8050/x64/Images/boot.wim.bcd BCD
initrd http://192.168.254.254:8050/boot.sdi boot.sdi
initrd http://192.168.254.254:8050/x64/Images/boot.wim boot.wim
boot || goto failed
goto start
:netboot
#chain --autofree http://boot.netboot.xyz/ipxe/netboot.xyz.efi
chain --autofree http://boot.netboot.xyz
boot || goto failed
goto start
:debian
set base-url http://deb.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64
kernel ${base-url}/linux console=ttyS1,115200n8
initrd ${base-url}/initrd.gz
boot
:rhel9
set base-url http://192.168.254.254:8050/rhel
initrd ${base-url}/initrd.img
kernel ${base-url}/vmlinuz inst.stage2=hd:LABEL=RHEL-9-4-0-BaseOS-x86_64
shim ${base-url}/BOOTX64.EFI
boot || goto failed
:fedora
set base-url http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/38/Server/x86_64/os/images/pxeboot
initrd ${base-url}/initrd.img
kernel ${base-url}/vmlinuz ip=dhcp ipv6.disable initrd=initrd.img
shim https://dl.fedoraproject.org/pub/archive/fedora/linux/releases/38/Server/x86_64/os/EFI/BOOT/BOOTX64.EFI
boot || goto failed
kernel ${dir}/linux ${install_params} ${mirrorcfg} -- quiet initrd=initrd.gz
initrd ${dir}/initrd.gz
boot || goto failed
goto start
Broken Ubuntu sections:
#item ubuntu Ubuntu
:ubuntu
set base-url http://archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64/
kernel ${base-url}/linux console=ttyS1,115200n8
initrd ${base-url}/initrd.gz
boot
:ubuntu2
set install_params auto=true priority=critical
set mirror http://archive.ubuntu.com
set base_dir ubuntu
set ubuntu_version bionic
set arch amd64
set mirrorcfg mirror/suite=${ubuntu_version}
set dir ${mirror}/${base_dir}/dists/${version}/main/installer-${arch}/current/images/netboot/ubuntu-installer/${arch}