Back to blog
FILE 0x8D·BUILDING A TPM-BYPASS WIN11 ISO WITH OFFLINE HIVE INJECTION

Building a TPM-bypass Win11 ISO with offline hive injection

May 7, 2026 · homelab, windows, pxe, iso

I wanted to PXE-boot a fully unattended Windows 11 25H2 install onto a VM with no TPM, no Secure Boot, and not enough RAM by Microsoft's reckoning. The usual LabConfig bypass keys in autounattend.xml weren't enough on the 25H2 setup UI.

What was happening

On 25H2, the "This PC must support TPM 2.0" gate fires from the setup UI before the windowsPE pass of autounattend runs. Which means the LabConfig\BypassTPMCheck registry keys never get applied — they're supposed to land via the unattend file, but the unattend file hasn't been parsed yet when the gate fires. The install dies at the hardware check screen.

The old trick of zeroing sources\appraiserres.dll to defeat the compatibility appraiser also didn't work alone on 25H2. The check is now upstream of the appraiser run.

What I found

If autounattend can't get the bypass keys into the registry in time, they need to be in the registry before setup boots. Which means writing them into the SYSTEM hive that lives inside sources\boot.wim — the WinPE image the setup UI loads.

The hive injection is offline: mount the wim, load the hive with reg load, add the keys, unload, commit, rebuild the ISO. The full v3 build script does:

# Mount the boot.wim index 2 (setup environment)
dism /Mount-Wim /WimFile:sources\boot.wim /Index:2 /MountDir:$mount

# Load the offline SYSTEM hive
reg load HKLM\BS_SYSTEM "$mount\Windows\System32\config\SYSTEM"

# Inject the bypasses
reg add HKLM\BS_SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f
reg add HKLM\BS_SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f
reg add HKLM\BS_SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f
reg add HKLM\BS_SYSTEM\Setup\LabConfig /v BypassCPUCheck /t REG_DWORD /d 1 /f
reg add HKLM\BS_SYSTEM\Setup\LabConfig /v BypassStorageCheck /t REG_DWORD /d 1 /f
reg add HKLM\BS_SYSTEM\Setup\MoSetup /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f

reg unload HKLM\BS_SYSTEM
dism /Unmount-Wim /MountDir:$mount /Commit

Then drop the autounattend.xml at the ISO root, zero appraiserres.dll anyway as belt-and-suspenders, and rebuild with oscdimg so both BIOS and UEFI boot paths work:

oscdimg.exe -m -o -u2 -udfver102 `
  -bootdata:"2#p0,e,b$iso\boot\etfsboot.com#pEF,e,b$iso\efi\microsoft\boot\efisys.bin" `
  $iso $output

The fix

That combination — hive-injected bypasses + autounattend + dual-boot ISO — boots through the hardware check unattended on a non-compliant VM. The unattend then runs the rest of the install: local admin, OpenSSH via FoD, Windows Defender Firewall off on all profiles, sleep/hibernate disabled, authorized_keys dropped, completion marker at C:\Users\Public\provisioned.txt.

Side note for anyone rebuilding ISOs from Linux: p7zip 16.02 can't read UDF-only ISOs that oscdimg -u2 produces. Either use a newer 7z, mount on a Windows host, or extract with xorriso on Linux.

What I'd do differently

I burned time on the SSH side of building the ADK toolchain. Installing the Windows ADK over SSH fails silently because the installer requires a SYSTEM session and SSH disconnects kill it. Schedule the install via Task Scheduler running as SYSTEM, not inline over SSH. Save yourself an afternoon.