Files
windows-unattend/CLAUDE.md
Timmy e106d749c7 修正兩處實機部署失敗的 XML bug;新增 DEPLOY.md 紀錄本機 USB 部署
- 根元素加上 xmlns:wcm / xmlns:xsi 命名空間宣告,否則全檔 wcm:action 無法解析(第 27 行第 9 欄即炸)
- ComputerName 改用 *,隨機後綴改由 FirstLogonCommands 的 Rename-Computer 產生;原本 PC-%RAND:5% 並非 Windows Setup 內建巨集,字面送入導致 specialize 階段 Shell-Setup 失敗
- 同步更正 CLAUDE.md / SUMMARY.md 對 %RAND:5% 的錯誤說明
- 新增 DEPLOY.md:/Volumes/Ventoy 的實際檔案佈局與重建步驟

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 18:59:35 +08:00

51 lines
5.8 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository nature
This is a **configuration template repo**, not a code project. It ships two artifacts:
- `unattend.xml` — the Windows Setup answer file.
- `ventoy.json` — the Ventoy Auto Install plugin config that tells Ventoy which ISO to pair with which template.
Deployment is via **[Ventoy](https://www.ventoy.net/)**, not Rufus or direct ISO modification. The user keeps a Ventoy USB with multiple Windows ISOs; `ventoy.json` at `/ventoy/ventoy.json` on the USB and `unattend.xml` at `/ventoy/script/unattend.xml` let Ventoy inject the answer file at boot without touching the ISO. Assume this Ventoy-based flow when reasoning about deploy-time behavior.
There is no build, no test suite, no package manager, and no runtime. Changes are validated by:
1. **Schema validation** via Windows SIM (Windows System Image Manager, part of Windows ADK).
2. **End-to-end VM test**: boot a VM from the Ventoy USB (or a Ventoy VHD) and confirm the install reaches the desktop without prompts. `QUICKSTART.md` has the exact steps.
There is no way to "run" this repo on the dev machine (macOS). All verification happens on a Windows target.
## The three-pass mental model
`unattend.xml` is not a flat config — it is split into three `<settings pass="...">` blocks that correspond to **three distinct moments in Windows Setup**. Each setting has a required pass; putting it in the wrong pass means Windows silently ignores it.
| Pass | When it runs | System state | What lives here |
|---|---|---|---|
| `windowsPE` | Booted from USB, Windows not yet installed | In-memory mini-OS | Disk partitioning, image selection, product key, EULA, WinPE UI language |
| `specialize` | Image applied, before first boot | `C:\` exists, no users yet | Computer name, timezone, registered owner, domain join |
| `oobeSystem` | First boot, OOBE running | Full Windows, waiting for account | Local account creation, AutoLogon, `FirstLogonCommands`, OOBE screen skips |
**Language settings appear twice on purpose** — once in `windowsPE` (`International-Core-WinPE`) for the installer UI, once in `oobeSystem` (`International-Core`) for the OOBE UI. That is not duplication; removing either will surface an unwanted language prompt.
## Non-obvious constraints when editing
- **Deployment is via Ventoy, not filename-based auto-detection.** The old "rename to `autounattend.xml` at USB root" trick does *not* apply here — Ventoy boots the ISO directly and injects the template per `ventoy.json`. Keep the repo filename as `unattend.xml` and keep the `ventoy.json` `template` path in sync.
- **`DiskID` uses the Ventoy variable `$$VT_WINDOWS_DISK_1ST_NONVTOY$$`, not a numeric literal.** Ventoy's Auto Install plugin substitutes this at runtime with the first non-Ventoy disk, so Windows doesn't wipe the Ventoy USB itself. **Never replace it with `0` or any hardcoded number.** Other Ventoy-provided variables (`$$VT_WINDOWS_DISK_MAX_SIZE$$`, `$$VT_WINDOWS_DISK_CLOSEST_<N>$$`) are valid substitutes for different selection policies but only work under Ventoy — they are meaningless if the XML is ever deployed via a non-Ventoy path.
- **Passwords appear twice**: once in `UserAccounts/LocalAccount` and once in `AutoLogon`. Both must match — changing one silently breaks AutoLogon.
- **`FirstLogonCommands` only fires if `AutoLogon.Enabled=true`**. Removing AutoLogon also disables the post-install script hand-off.
- **`Order` values within `FirstLogonCommands` / `CreatePartitions` / `ModifyPartitions` must be unique and contiguous** — duplicates cause silent skips.
- **The disk config assumes UEFI+GPT and wipes the selected disk unconditionally** (`WillWipeDisk=true`). Any BIOS/MBR target requires rewriting `<DiskConfiguration>`; there is no runtime branching.
- **`processorArchitecture="amd64"`** is hardcoded on every `<component>`. ARM64 deployments require a global find-and-replace to `arm64`.
- **Password is plaintext** (`<PlainText>true</PlainText>`). This is a deliberate testing-only choice documented in `SUMMARY.md`. For production, generate Base64 via Windows SIM; do not hand-encode.
- **`ComputerName` does not support `%RAND:5%` or any other macro.** Windows Setup only accepts a literal name, `*` (auto-generate a random name like `DESKTOP-ABC123D`), or an empty value. `%RAND:N%` is an MDT/SCCM task-sequence variable — under the Ventoy → raw `unattend.xml` path it is passed verbatim as a literal string, fails NetBIOS character validation (`%` is not allowed), and causes the specialize pass to abort with a `Microsoft-Windows-Shell-Setup` error. If a `PC-XXXXX` style name is required, set `<ComputerName>*</ComputerName>` here and do the rename in `FirstLogonCommands` via `Rename-Computer` (a reboot is needed for it to take effect — combine with the existing `shutdown /r` step). (Distinct from `$$VT_*$$`, which *is* a real Ventoy pre-processor substitution.)
- **`FirstLogonCommands` references `C:\Scripts\Setup.ps1`** but this repo does **not** contain that script. It is expected to be placed on the target by other means (baked into the image, copied from USB earlier in `FirstLogonCommands`, or pulled from network).
## When making changes
- Preserve the `xmlns="urn:schemas-microsoft-com:unattend"` namespace and the `wcm:action="add"` attributes on list items — Windows SIM emits these and Setup requires them.
- Every `<component>` needs all four identity attributes: `name`, `processorArchitecture`, `publicKeyToken="31bf3856ad364e35"`, `language="neutral"`, `versionScope="nonSxS"`.
- The Chinese-language docs (`README.md`, `QUICKSTART.md`, `SUMMARY.md`) explain the *why* behind design decisions — consult `SUMMARY.md` before proposing structural changes, as several current choices are explicit tradeoffs, not oversights.