diff --git a/CLAUDE.md b/CLAUDE.md index 52fbbc2..874bb56 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,7 +40,7 @@ There is no way to "run" this repo on the dev machine (macOS). All verification - **The disk config assumes UEFI+GPT and wipes the selected disk unconditionally** (`WillWipeDisk=true`). Any BIOS/MBR target requires rewriting ``; there is no runtime branching. - **`processorArchitecture="amd64"`** is hardcoded on every ``. ARM64 deployments require a global find-and-replace to `arm64`. - **Password is 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. -- **`%RAND:5%`** in `ComputerName` is a Windows Setup built-in, not a shell variable — don't try to "fix" it. (Distinct from `$$VT_*$$` which is a Ventoy pre-processor substitution.) +- **`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 diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..60537b2 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,101 @@ +# DEPLOY — 本機 Ventoy USB 部署紀錄 + +這份文件記錄本機 Ventoy USB(`/Volumes/Ventoy`)上 `unattend.xml` 與 `ventoy.json` 的實際部署方式,供下次換機、換 ISO、或刷新 USB 內容時照著做。 + +概念與疑難排解請看 `QUICKSTART.md`;這份只寫「這顆 USB 目前的樣子」和「怎麼重建它」。 + +--- + +## 目前 USB 內容 + +掛載點:`/Volumes/Ventoy` + +USB 根目錄兩個 ISO: + +| 檔名 | 用途 | +|---|---| +| `Windows 11_25H2_Chinese_Traditional_x64v1.iso` | Win11 25H2 繁中 x64 | +| `Windows 10_22H2_Chinese_Traditional_x64v1.iso` | Win10 22H2 繁中 x64 | + +注入檔案佈局: + +``` +/Volumes/Ventoy/ +├── Windows 11_25H2_Chinese_Traditional_x64v1.iso +├── Windows 10_22H2_Chinese_Traditional_x64v1.iso +└── ventoy/ + ├── ventoy.json ← 對應兩個 ISO,都指向同一份 template + └── script/ + └── unattend.xml ← 與 repo 根目錄的 unattend.xml 相同 +``` + +--- + +## USB 上的 `ventoy.json` + +**與 repo 根目錄的 `ventoy.json` 不同** —— repo 版本保留通用示範路徑 `/Win11.iso`,USB 版本則綁定本機這兩個 ISO 的實際檔名: + +```json +{ + "auto_install": [ + { + "image": "/Windows 11_25H2_Chinese_Traditional_x64v1.iso", + "template": "/ventoy/script/unattend.xml" + }, + { + "image": "/Windows 10_22H2_Chinese_Traditional_x64v1.iso", + "template": "/ventoy/script/unattend.xml" + } + ] +} +``` + +- `image` 路徑以 `/` 開頭,相對 USB 根目錄,**完整檔名必須跟 USB 上一字不差**(含空格、底線、版本號)。 +- 兩個 ISO 共用同一份 `unattend.xml`;該 XML 目前以 UEFI+GPT 全碟清除方式部署,兩個版本皆適用。 +- 若日後只想其中一個 ISO 走自動安裝、另一個保留互動安裝,刪掉對應的物件即可;Ventoy 找不到對應 `image` 時會走一般安裝流程。 + +--- + +## 重新部署步驟(macOS) + +插入 Ventoy USB 後: + +```bash +# 從 repo 根目錄執行 +mkdir -p /Volumes/Ventoy/ventoy/script +cp unattend.xml /Volumes/Ventoy/ventoy/script/unattend.xml + +# 寫 ventoy.json(見上一節內容,或直接手編) +# 注意:image 檔名必須跟 USB 上的 ISO 檔名完全一致 + +# 清掉 macOS 複製過程產生的 ._ AppleDouble metadata +dot_clean /Volumes/Ventoy/ventoy +``` + +驗證: + +```bash +ls /Volumes/Ventoy/ventoy/ /Volumes/Ventoy/ventoy/script/ +diff unattend.xml /Volumes/Ventoy/ventoy/script/unattend.xml # 應無輸出 +cat /Volumes/Ventoy/ventoy/ventoy.json +``` + +--- + +## 換 ISO 時要改什麼 + +1. 把新 ISO 丟到 USB 根目錄。 +2. 編輯 `/Volumes/Ventoy/ventoy/ventoy.json`,把對應條目的 `image` 換成新檔名(或新增一條)。 +3. **不用**動 `/Volumes/Ventoy/ventoy/script/unattend.xml`,除非要改 Windows 版本特有設定。 +4. 若 repo 裡的 `unattend.xml` 有更新,重跑一次 `cp` 與 `dot_clean` 即可。 + +--- + +## 本次部署已知限制 + +沿用 repo 預設值,下列情況會失敗,改用前要先處理: + +- **目標機若是 BIOS/MBR**:`<DiskConfiguration>` 目前寫死 UEFI+GPT,分割階段會報錯。 +- **ARM64 機器**:所有 `<component>` 的 `processorArchitecture="amd64"` 要改成 `arm64`。 +- **`C:\Scripts\Setup.ps1` 未提供**:`FirstLogonCommands` 會在首次登入時報「找不到檔案」。解法:在 `FirstLogonCommands` 前段加一條從 USB 複製的指令,或另外烘進 image,或乾脆刪掉 `Order=1` 那條 `SynchronousCommand`。 +- **密碼是明碼**(`<PlainText>true</PlainText>`):僅適合測試用途;正式部署請用 Windows SIM 產 Base64。 diff --git a/SUMMARY.md b/SUMMARY.md index f8dc714..bfd24cf 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -33,7 +33,7 @@ Windows 給的答案叫 **Answer File**(回應檔,通常是 `unattend.xml` - **磁碟分割是硬寫的**:清空 Disk 0 → EFI 500 MB → MSR 128 MB → 剩下全給 Windows。不讓 Setup 自己猜,不處理遷移場景。 - **語系/時區是硬寫的**:`zh-TW` + `Taipei Standard Time`。不依賴 OEM image 預設。 -- **唯一的例外是電腦名稱**:`PC-%RAND:5%` 刻意引入隨機,因為「確定性」遇到「多台部署不可重名」時要讓路給後者。 +- **唯一的例外是電腦名稱**:XML 裡設 `<ComputerName>*</ComputerName>` 讓 Windows Setup 先給一個隨機名(否則 specialize 階段會因為 `%RAND:5%` 之類的假巨集字面送入而失敗),再由 `FirstLogonCommands` 的 `Rename-Computer` 把它改成 `PC-XXXXX` 格式並在收尾 `shutdown /r` 時一起生效。 這是一個取捨:確定性優先,但在會造成衝突的地方(主機名)讓步。 diff --git a/unattend.xml b/unattend.xml index 21da813..55919fb 100644 --- a/unattend.xml +++ b/unattend.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> -<unattend xmlns="urn:schemas-microsoft-com:unattend"> +<unattend xmlns="urn:schemas-microsoft-com:unattend" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- Pass 1: windowsPE — 安裝前的基本設定 --> <settings pass="windowsPE"> @@ -80,7 +82,7 @@ publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> - <ComputerName>PC-%RAND:5%</ComputerName> + <ComputerName>*</ComputerName> <TimeZone>Taipei Standard Time</TimeZone> <RegisteredOwner>IT Department</RegisteredOwner> <RegisteredOrganization>YourCompany</RegisteredOrganization> @@ -158,6 +160,11 @@ </SynchronousCommand> <SynchronousCommand wcm:action="add"> <Order>3</Order> + <CommandLine>powershell.exe -NoProfile -Command "Rename-Computer -NewName ('PC-' + (Get-Random -Minimum 10000 -Maximum 100000)) -Force"</CommandLine> + <Description>主機名改成 PC-XXXXX(重開後生效)</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>4</Order> <CommandLine>shutdown /r /t 5</CommandLine> <Description>完成後重開機</Description> </SynchronousCommand>