Fully unattended Windows 11 Pro build using Autounattend.xml, swtpm for TPM 2.0 emulation, and VirtIO drivers. Five PowerShell provisioners strip bloatware, telemetry, unused services, and apply performance tuning for a resource-constrained host. Output is a compressed QCOW2 image. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lite-win
A repeatable, minimal Windows 11 Pro VM image built with Packer and QEMU/KVM. No bloatware, no Microsoft account requirement, no unnecessary services.
Designed for a resource-constrained Linux host running Fedora with QEMU/KVM.
What it does
- Boots the Windows 11 Pro ISO fully unattended via
Autounattend.xml - Partitions the disk (GPT/UEFI), installs Windows, configures WinRM
- Runs five PowerShell provisioner scripts over WinRM:
- Removes ~30 built-in apps and OneDrive
- Disables telemetry, Cortana, advertising ID, and CEIP
- Disables resource-heavy services (SysMain, Windows Search, Xbox, etc.)
- Applies performance tweaks (High Performance power plan, fixed page file, no animations)
- Cleans up temp files and compacts the OS
- Produces a thin-provisioned, compressed QCOW2 disk image (~12–15 GB)
Prerequisites
Install these on the Fedora host before building:
sudo dnf install -y qemu-kvm swtpm edk2-ovmf packer
Packer may not be in the Fedora repos depending on your version. If
dnfdoesn't find it, download the Linux AMD64 binary from releases.hashicorp.com/packer and place it in~/.local/bin/.
You also need:
- Windows 11 Pro retail ISO — download from microsoft.com/software-download/windows11 (select the x64 multi-edition ISO)
- VirtIO drivers ISO — downloaded automatically by
make virtio-iso
Quick start
# 1. Download VirtIO drivers
make virtio-iso
# 2. Create your local variable file
cp variables.pkrvars.hcl.example variables.pkrvars.hcl
Edit variables.pkrvars.hcl and set:
win_iso_path = "/path/to/Win11_24H2_English_x64.iso"
win_iso_checksum = "sha256:<output of: sha256sum /path/to/Win11_*.iso>"
# 3. Build
make build
The finished image lands in output/windows11-lite.
Running the image
Recommended: virt-install (repeatable)
virt-install \
--name windows11-lite \
--memory 4096 \
--vcpus 2 \
--disk output/windows11-lite,format=qcow2,bus=virtio \
--import \
--os-variant win11 \
--network network=default,model=virtio \
--graphics spice,listen=none \
--video qxl \
--boot uefi \
--tpm emulator,model=tpm-tis,version=2.0 \
--noautoconsole
Then connect with virt-manager or virt-viewer windows11-lite.
virt-manager GUI
- File → New VM → Import existing disk image
- Browse to
output/windows11-lite; set OS to Windows 11 - Set RAM and CPUs, then Customize configuration before install
- Set Firmware →
UEFI x86_64(not BIOS) - Set disk Bus →
VirtIO - Add Hardware → TPM → Emulated, TIS, version 2.0
- Begin installation
All three settings — UEFI boot, VirtIO disk bus, TPM 2.0 — are required. The image was built against them; mismatching any one causes a boot failure.
Windows activation
The build uses the generic KMS client key W269N-WFGWX-YVC9B-4J6C9-T83GX to allow unattended installation. This is not an activation key. Activate Windows with your own license after the build.
Variables reference
| Variable | Default | Description |
|---|---|---|
win_iso_path |
— | Required. Absolute path to the Windows 11 ISO |
win_iso_checksum |
— | Required. sha256:<hash> of the ISO |
virtio_iso_path |
virtio-win.iso |
Path to VirtIO drivers ISO |
vm_name |
windows11-lite |
Output image name |
disk_size |
51200 |
Virtual disk size in MB (50 GB) |
memory |
4096 |
RAM in MB during the Packer build |
cpus |
2 |
vCPUs during the Packer build |
output_directory |
output |
Output directory for the QCOW2 image |
winrm_password |
Packer1234! |
Build-time WinRM password — must match Autounattend.xml |
ovmf_code |
/usr/share/edk2/ovmf/OVMF_CODE.fd |
UEFI firmware code (Fedora default) |
ovmf_vars |
/usr/share/edk2/ovmf/OVMF_VARS.fd |
UEFI firmware vars template (Fedora default) |
All variables except win_iso_path and win_iso_checksum have usable defaults.
Project structure
.
├── build.sh # Starts swtpm, runs packer, cleans up on exit
├── Makefile # Convenience targets
├── windows11.pkr.hcl # Packer template
├── variables.pkrvars.hcl.example # Variable template (copy → variables.pkrvars.hcl)
├── http/
│ └── Autounattend.xml # Unattended Windows install answer file
└── scripts/
├── 01-debloat-apps.ps1 # Remove built-in apps and OneDrive
├── 02-disable-telemetry.ps1 # Disable telemetry, Cortana, CEIP
├── 03-disable-services.ps1 # Disable unnecessary services
├── 04-performance.ps1 # Power plan, page file, visual effects
└── 05-cleanup.ps1 # DISM cleanup, temp purge, Compact OS
Make targets
| Target | Description |
|---|---|
make build |
Build the VM image (default) |
make validate |
Validate Packer config without building |
make init |
Install Packer plugins |
make virtio-iso |
Download the VirtIO drivers ISO |
make clean |
Remove build output |
make distclean |
Remove build output and downloaded ISOs |