Files
lite-win/README.md
jacob.b.nelson2 e4741ccc96 Initial commit: Packer + QEMU/KVM Windows 11 minimal VM
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>
2026-05-17 19:31:18 -05:00

158 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (~1215 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 |