This guide assumes that you have a Fedora 34 server or workstation system configured to run Cobbler v3.3.7 similarly to the Cobbler v3.3.6 Beginner’s guide.
Starting where the Beginner’s guide left off, further configure the Cobbler v3.3.7 server to deploy both Windows 10 and Windows 11 via PXE network boot, using the same system and network environment. This guide assumes that you still have selinux and firewalld configured and enabled as described in the Beginner’s guide.
IMPORTANT: There was a frequent issue on PXE clients using VirtualBox EFI firmware. For this reason, it is recommended to run both Cobbler server and PXE client as either bare metal systems or VMWare Workstation/Fusion or HyperV VMs for UEFI installations.
This guide assumes you have already acquired the Windows 10 and 11 64-bit ISO installation files by using the Windows 10 and Windows 11 Media Creation Tool
Also on the Windows 11 download page linked above is the minumum system requirements for installing Windows 11, which include UEFI Secure Boot and TPM support, making a supported installation to a VM an advanced topic beyond the scope of this guide.
Enable the Windows support features as well as iPXE configs in Cobbler.
Install some additional dependencies required by Cobbler
yum install -y samba python-hivex python-pefile wimlib-utils python3-ldap openldap-servers openldap-clients
systemctl enable smb
Enable Windows support in Cobbler’s settings, as well as ipxe, if not enabled already
sed -i 's/windows_enabled: false/windows_enabled: true/' /etc/cobbler/settings.d/windows.settings
sed -i "s/enable_ipxe: false/enable_ipxe: true/" /etc/cobbler/settings.yaml
systemctl restart cobblerd
Download the wimboot image from iPXE’s GitHub to the Cobbler loaders directory and sync cobbler
loaders directory if not done already (since the PXE software included with VMWare Workstation/Fusion and VirtualBox VMs do not support downloads via HTTP).wget https://github.com/ipxe/wimboot/releases/latest/download/wimboot -P /var/lib/cobbler/loaders
ln -s /usr/share/ipxe/undionly.kpxe /var/lib/cobbler/loaders/.
ln -s /usr/share/ipxe/ipxe-x86_64.efi /var/lib/cobbler/loaders/.
ln -s /usr/share/ipxe/ipxe-snponly-x86_64.efi /var/lib/cobbler/loaders/.
cobbler sync
Edit the /etc/samba/smb.conf file to match the below text-block
[global]
server role = standalone
log level = 5
load printers = no
security = USER
map to guest = Bad User
guest account = nobody
[DISTRO]
path = /var/www/cobbler
public = yes
browseable = yes
writeable = no
printable = no
More info on this service and configuration in the Tips & Troubleshooting section below
Enable and start the SMB service
systemctl enable --now smb
Now, fix the dhcp.template file to properly detect PXE client firmware type during DHCP and enable iPXE chainloading for a more reliable experience on PXE clients.
sed -i 's,filename "http://\\\$cobbler_server/cblr/svc/op/ipxe/system/\\\$iface.owner";,filename "http://\$cobbler_server/cblr/svc/op/ipxe/system/\$iface.owner";\\n } else if exists system-arch and option system-arch = 00:07 {\\n filename "ipxe-x86_64.efi";\\n } else if exists system-arch and option system-arch = 00:08 {\\n filename "ipxe-x86_64.efi";\\n } else if exists system-arch and option system-arch = 00:09 {\\n filename "ipxe-x86_64.efi";,' /etc/cobbler/dhcp.template
The above command should edit the below original text block to match the following updated block in the resulting dhcp.template file:
original
#if $iface.enable_ipxe:
if exists user-class and option user-class = "iPXE" {
filename "http://$cobbler_server/cblr/svc/op/ipxe/system/$iface.owner";
} else {
filename "undionly.kpxe";
}
#end if
updated
#if $iface.enable_ipxe:
if exists user-class and option user-class = "iPXE" {
filename "http://$cobbler_server/cblr/svc/op/ipxe/system/$iface.owner";
} else if exists system-arch and option system-arch = 00:07 {
filename "ipxe-x86_64.efi";
} else if exists system-arch and option system-arch = 00:08 {
filename "ipxe-x86_64.efi";
} else if exists system-arch and option system-arch = 00:09 {
filename "ipxe-x86_64.efi";
} else {
filename "undionly.kpxe";
}
#end if
Finally, enable SELinux and Firewalld allowances for SMB server
setsebool -P samba_export_all_ro 1
setsebool -P cobbler_use_cifs 1
firewall-cmd --permanent --zone=cobbler --add-service=samba
firewall-cmd --reload
mount the Windows 10 installation media and import the distro into cobbler:
mkdir /mnt/Windows10
mount -o ro,loop ~/Downloads/Win10_22H2_English_x64.iso /mnt/Windows10
cobbler import --name Win10 --path /mnt/Windows10
Optional: If the PXE client will use legacy-BIOS firmware instead of UEFI, toggle uefi to false in the Cobbler Profile autoinstallation metadata:
cobbler profile edit --name Win10-x86_64 --autoinstall-meta 'uefi'='false' --in-place
More info in Cobbler’s official docs.
Finally, create a new Cobbler System to PXE boot and automatically install Windows 10 Pro, replacing the “aa:bb:cc:dd:ee:ff” with the MAC address of your PXE client, being sure not to use a duplicate MAC address of any other Cobbler System, then sync up Cobbler.
cobbler system add --name Win10 --profile Win10-x86_64 --mac-address "aa:bb:cc:dd:ee:ff" --netboot-enabled true --enable-ipxe true
cobbler sync
The PXE Client VM can now be powered on, and should automatically boot to PXE and install Windows 10 to the VM HDD using the “autounattended.xml” answerfile.
Optional: If installing Windows 11 on unsupported hardware, use the following commands to edit the startnet.template file in order to bypass hardware requirements for the PXE client.
CMD1=$(echo 'reg add HKLM\\SYSTEM\\Setup\\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f' | unix2dos)
CMD2=$(echo 'reg add HKLM\\SYSTEM\\Setup\\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f' | unix2dos)
CMD3=$(echo 'reg add HKLM\\SYSTEM\\Setup\\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f' | unix2dos)
CMD4=$(echo 'reg add HKLM\\SYSTEM\\Setup\\LabConfig /v BypassCPUCheck /t REG_DWORD /d 1 /f' | unix2dos)
CMD5=$(echo 'reg add HKLM\\SYSTEM\\Setup\\LabConfig /v BypassStorageCheck /t REG_DWORD /d 1 /f' | unix2dos)
CMD6=$(echo '\$distro_share\\sources\\setup.exe \$unattended' | unix2dos)
sed -i -E "s,^#else.?$,#else if \$os_version == \"11\"\n${CMD1}\n${CMD2}\n${CMD3}\n${CMD4}\n${CMD5}\n${CMD6}\n#else," /etc/cobbler/windows/startnet.template
Now, take similar steps as with Windows 10 to import and automatically deploy Windows 11 Pro over PXE.
mkdir /mnt/Windows11
mount -o ro,loop ~/Downloads/Win11_24H2_English_x64.iso /mnt/Windows11
cobbler import --name Win11 --path /mnt/Windows11
cobbler system add --name Win11 --profile Win11-x86_64 --mac-address "aa:bb:cc:dd:ee:ff" --netboot-enabled true --enable-ipxe true
cobbler sync
The PXE Client VM can now be powered on, and should automatically boot to PXE and install Windows 11 to the VM HDD using the “autounattended.xml” answerfile template.
The Cobbler 3.3.6 Beginner’s Guide Tips & Troubleshooting section contains some basic recommendations and limitations of Cobbler which will not be repeated here.
It’s important to understand how Cobbler manages Windows distros and deployments by default, as there are certain implicit limitations not present with other distros.
Cobbler has 3 main templates for Windows distro management, all located in /etc/cobbler/windows directory (instead of the usual /var/lib/cobbler/templates and /var/lib/cobbler/scripts directories), which effectively limit Windows deployments to cobbler profile level customizations
startnet.template: Generates “startnet.cmd” which gets archived/compressed into the WinPE image (loaded from PXE) in order to start Windows setup.exe on the PXE client with the associated Answerfile
answerfile.template: Generates “autounattended.xml” answerfile with profile attributes to be retrieved over SMB by PXE clients for unattended installations.
post_ins_cmd.template: Generates “post_install.cmd” which is used in the Answerfile to retrieve the autoinstall file (post-install script) defined for the profile
/var/lib/cobbler/templates/win.ks has no effect.The autoinstall-meta parameters (used to specify the boot files and how to download them, answerfile and post_install templates for unattended installations, as well as set firmware/partitioning mode) can be configured at the cobbler system (or profile) level and given unique names to generate different files for use by diffrent profiles or systems, but neither the answerfile.template or post_inst_cmd.template files are system-level aware, they only consist of profile-level settings.
cobbler system items, in addition to the above autoinstall-meta parameters, which have limited functionality for Systems.Windows is limited in the ways to provide an Answerfile, it cannot be specified in boot/kernel parameters like many linux distros
This is all only default behavior in cobbler, and it would be possible to program additional logic into the startnet.cmd or post_install.cmd scripts, for instance, to retrieve a diffent answerfile or post-install script based on the hostname (configurable through DHCP) or MAC address. However, that would come with additional limitations and requirements beyond the scope of this guide.
VirtualBox Issues
Specifially, the ipxe-x86_64.efi bootloader would fail to “initialize devices” and even though using the ipxe-snponly-x86_64.efi bootloader would load properly, the PXE client VM would usually just hang when downloading one of the WinPE files (i.e. wimboot, boot.sdi, bootmgr.exe, bcd, winpe.wim)
Tried several troubleshooting steps and could not get a consistent fix:
Tried different virtual network adapters.
Tried running PXE client on another host PC with different VirtualBox version
Tried installing the appropriate VirtualBox Extensions for my version of VB.
Disabled Memory Isolation in Windows Security (and other security options) on VirtualBox Host.
Tried with and without “Virtual Machine Platform” and “Windows Hypervisor Platform” Windows Features installed/enabled.
Tried compiling latest and previous versions of ipxe.efi (snp, intel, realtek, etc…) bootloader from source
Found no relevant entries/errors in VirtualBox VM logs (debug logs enabled) or Windows Event Viewer and nothing abnormal in Cobbler server logs (HTTP, TFTP, DHCP).
A live Windows 10 installation can be easily converted from MBR (legacy-BIOS) to GPT (UEFI) via powershell commands, which can be used as a workaround for compatibility with VirtualBox UEFI firmware
start-net.cmd issue
The smb linux service used to host the installation files for the PXE client on the Cobbler server would be unresponsive during some installations, primarily when running the startnet.cmd script on the PXE client to start Windows Setup, which caused the installation to stall and error-out occasionally.
After reading through the manpage (man smb.conf) and trying several different configurations the problem persisted
Make the following edit to the startnet.template file to account for this occasional unresponsiveness/lag from the SMB server by first enumerating the SMB share until it responds.
CMD=$(echo 'dir \$distros_dir || GOTO wno20' | unix2dos)
sed -i "s,net use z:,${CMD}\nnet use z:," /etc/cobbler/windows/startnet.template
References
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/automate-windows-setup
https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/
https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/wsim/answer-files-overview
https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/oobexml-in-windows-11
https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/customize-oobe-in-windows-11
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-oobexml
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/oobexml-settings
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/how-oobexml-works
https://learn.microsoft.com/en-us/windows/deployment/configure-a-pxe-server-to-load-windows-pe
https://cobbler.readthedocs.io/en/latest/user-guide/wingen.html
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/winpe-intro
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/automate-windows-setup