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>
158 lines
5.3 KiB
Markdown
158 lines
5.3 KiB
Markdown
# lite-win
|
||
|
||
A repeatable, minimal Windows 11 Pro VM image built with [Packer](https://www.packer.io/) 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
|
||
|
||
1. Boots the Windows 11 Pro ISO fully unattended via `Autounattend.xml`
|
||
2. Partitions the disk (GPT/UEFI), installs Windows, configures WinRM
|
||
3. 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
|
||
4. Produces a thin-provisioned, compressed QCOW2 disk image (~12–15 GB)
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
Install these on the Fedora host before building:
|
||
|
||
```bash
|
||
sudo dnf install -y qemu-kvm swtpm edk2-ovmf packer
|
||
```
|
||
|
||
> **Packer** may not be in the Fedora repos depending on your version. If `dnf` doesn't find it, download the Linux AMD64 binary from [releases.hashicorp.com/packer](https://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](https://www.microsoft.com/software-download/windows11) (select the x64 multi-edition ISO)
|
||
- **VirtIO drivers ISO** — downloaded automatically by `make virtio-iso`
|
||
|
||
---
|
||
|
||
## Quick start
|
||
|
||
```bash
|
||
# 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:
|
||
|
||
```hcl
|
||
win_iso_path = "/path/to/Win11_24H2_English_x64.iso"
|
||
win_iso_checksum = "sha256:<output of: sha256sum /path/to/Win11_*.iso>"
|
||
```
|
||
|
||
```bash
|
||
# 3. Build
|
||
make build
|
||
```
|
||
|
||
The finished image lands in `output/windows11-lite`.
|
||
|
||
---
|
||
|
||
## Running the image
|
||
|
||
### Recommended: virt-install (repeatable)
|
||
|
||
```bash
|
||
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
|
||
|
||
1. **File → New VM → Import existing disk image**
|
||
2. Browse to `output/windows11-lite`; set OS to *Windows 11*
|
||
3. Set RAM and CPUs, then **Customize configuration before install**
|
||
4. Set **Firmware** → `UEFI x86_64` (not BIOS)
|
||
5. Set disk **Bus** → `VirtIO`
|
||
6. **Add Hardware → TPM** → Emulated, TIS, version 2.0
|
||
7. 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 |
|