Files
windows-unattend/DEPLOY.md
Timmy b1e5b6912a unattend.xml 直接以 User(首字大寫)建帳號;Setup.ps1 拿掉 rename-LocalUser
把 Order 3 的 net user 命令直接寫成 net user User,省掉「先建小寫 user 再
Rename-LocalUser 改成大寫 User」這個迂迴。Setup.ps1 的 rename-hide-accounts
段同時改名為 hide-admin-account,內容只剩設 SpecialAccounts\\UserList\\Admin=0
這一行——隱藏 Admin 仍然由 Setup.ps1 負責。

文件全部同步:DEPLOY/QUICKSTART/SUMMARY/README/CLAUDE 把「先建小寫再改名」的
bulletproof 解釋與相關段名都拿掉。

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

226 lines
14 KiB
Markdown
Raw 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.
# 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 相同
└── Setup.ps1 ← 與 repo 根目錄的 Setup.ps1 相同(首次登入自動複製到 C:\Scripts\
```
`Setup.ps1` **必須跟 unattend.xml 放在同一個 `/ventoy/script/` 目錄下**`unattend.xml``FirstLogonCommands` Order 4 會掃所有掛載的磁碟,找到第一個有 `\ventoy\script\Setup.ps1` 的就複製到 `C:\Scripts\Setup.ps1`,所以這個路徑寫死,不能搬。
---
## USB 上的 `ventoy.json`
**與 repo 根目錄的 `ventoy.json` 不同** —— repo 版本保留通用示範路徑 `/Win11.iso`USB 版本則綁定本機這兩個 ISO 的實際檔名,並帶了 `menu_tip` 讓 Ventoy 選單上顯示每個 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"
}
],
"menu_tip": {
"left": "10%",
"top": "81%",
"color": "white",
"tips": [
{
"image": "/Windows 11_25H2_Chinese_Traditional_x64v1.iso",
"tip": "Win11 25H2 自動安裝清碟→Admin/P@ssw0rd!→裝 Telegram→重開UEFI+GPT會清空目標碟"
},
{
"image": "/Windows 10_22H2_Chinese_Traditional_x64v1.iso",
"tip": "Win10 22H2 自動安裝清碟→Admin/P@ssw0rd!→裝 Telegram→重開UEFI+GPT會清空目標碟"
}
]
}
}
```
- `image` 路徑以 `/` 開頭,相對 USB 根目錄,**完整檔名必須跟 USB 上一字不差**(含空格、底線、版本號)。`menu_tip.tips[].image` 也要跟著同步,否則光標移到 ISO 上不會跳 tip。
- 兩個 ISO 共用同一份 `unattend.xml`;該 XML 目前以 UEFI+GPT 全碟清除方式部署,兩個版本皆適用。
- 若日後只想其中一個 ISO 走自動安裝、另一個保留互動安裝,刪掉 `auto_install` 對應的物件即可Ventoy 找不到對應 `image` 時會走一般安裝流程(`menu_tip` 那條保留沒關係,不跳 auto install
- `menu_tip.tip` 是**單行**的;[Ventoy 文件](https://www.ventoy.net/en/plugin_menutip.html)明確說不支援 `\n`,換行會被一律忽略。要多行提示只能靠縮寫或另加 plugin`menu_alias`)。
---
## 重新部署步驟macOS
插入 Ventoy USB 後:
```bash
# 從 repo 根目錄執行
mkdir -p /Volumes/Ventoy/ventoy/script
cp unattend.xml /Volumes/Ventoy/ventoy/script/unattend.xml
cp Setup.ps1 /Volumes/Ventoy/ventoy/script/Setup.ps1
# 寫 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 # 應無輸出
diff Setup.ps1 /Volumes/Ventoy/ventoy/script/Setup.ps1 # 應無輸出
cat /Volumes/Ventoy/ventoy/ventoy.json
```
**改 `Setup.ps1` 後沒重新 `cp` 是部署最常見的失誤**FirstLogonCommands 從 USB 讀的是 `/ventoy/script/Setup.ps1` 那份repo 裡改了不會自己同步上去。每次調 Setup.ps1 都要記得跑 `cp Setup.ps1 /Volumes/Ventoy/ventoy/script/Setup.ps1``dot_clean`
---
## 換 ISO 時要改什麼
1. 把新 ISO 丟到 USB 根目錄。
2. 編輯 `/Volumes/Ventoy/ventoy/ventoy.json`,把對應條目的 `image` 換成新檔名(或新增一條)。
3. **不用**動 `/Volumes/Ventoy/ventoy/script/unattend.xml``Setup.ps1`,除非要改 Windows 版本特有設定。
4. 若 repo 裡的 `unattend.xml``Setup.ps1` 有更新,重跑一次 `cp``dot_clean` 即可。
---
## 部署後動作FirstLogonCommands 做了什麼)
目標機首次登入 `Admin` 帳號時,下列動作會按 `Order` 依序執行(全部跑完才 reboot
| Order | 動作 | 需要網路? |
|---|---|---|
| 1 | `net accounts /maxpwage:unlimited`(密碼永不過期) | 否 |
| 2 | `Rename-Computer` 把主機名改成 `PC-XXXXX`(重開後生效) | 否 |
| 3 | `net user User 1234 /add``/logonpasswordchg:yes`(建立一般使用者 `User`,首次登入強制改密) | 否 |
| 4 | 掃磁碟找 `\ventoy\script\Setup.ps1` 並複製到 `C:\Scripts\Setup.ps1`log: `firstlogon-copysetup.log` | 否(從 Ventoy USB 讀) |
| 5 | `powershell -File C:\Scripts\Setup.ps1`13 段 post-install見下節log: `setup.log` | 大部分 **是** |
| 6 | `shutdown /r /t 5` 重開機 | 否 |
Order 4/5 是改版重點:把原本散在 `FirstLogonCommands` 裡的 OpenSSH / Telegram / RemoveWindowsAI 三條搬進 `Setup.ps1`,並補上 10 個新動作。
### `Setup.ps1` 做了什麼13 段,按執行順序)
每段都用 `Section` 包裝,會把 `=== <name> START/DONE/ERR ===` 寫到 `C:\Windows\Temp\setup.log`,可以照名字逐段排查。
**Phase 1不需網路、本機設定**
| 段名 | 在做什麼 |
|---|---|
| `firewall-ssh-22` | 建 `SSH TCP 22 (Allow Inbound)` 防火牆規則,三個 profile 都啟用 |
| `rdp-enable-3389` | `fDenyTSConnections=0``UserAuthentication=1`、啟用 `Remote Desktop` 防火牆群組 |
| `icmp-echo-allow` | 允許 ICMPv4 Echo Request inbound讓外部 ping 得到) |
| `winrm-enable` | `Enable-PSRemoting``winrm quickconfig``Basic`/`AllowUnencrypted=true``TrustedHosts=*` |
| `onedrive-remove` | 殺 OneDrive process、跑兩處 `OneDriveSetup.exe /uninstall`、清啟動鍵與 CLSID、刪殘留資料夾 |
| `cortana-websearch-off` | `AllowCortana=0``DisableWebSearch=1``ConnectedSearchUseWeb=0``DisableSearchBoxSuggestions=1` |
| `apply-ui-ime-default-profile` | `reg load` Default profile NTUSER.DAT寫入顯示副檔名/隱藏檔、工作列靠左、Dark mode、隱藏搜尋框、停 Spotlight、英數鍵盤排第一+注音排第二、CHT 預設英數模式、停切換 Hotkey |
| `hide-admin-account` | `SpecialAccounts\UserList\Admin=0`(從登入畫面隱藏 Admin帳號仍存在仍可登入 |
**Phase 2需網路、最多等 60 秒):**
| 段名 | 在做什麼 |
|---|---|
| `wait-network` | 最多 30 回合×2 秒等 ICMP 通到 8.8.8.8 |
| `openssh-server-install` | `Add-WindowsCapability OpenSSH.Server``Set-Service sshd Automatic``Start-Service sshd` |
| `kms-activate` | 依序試 `$InternalKmsServers``$PublicKmsServers`kms.digiboy.ir 等),跑 `slmgr /skms``/ato`,遇到第一個 `successful/成功` 就跳出 |
| `winget-install-chrome` | `winget install Google.Chrome --silent --scope machine`Win10 沒裝 App Installer 會 skip |
| `remove-windows-ai` | `irm https://raw.githubusercontent.com/zoicware/RemoveWindowsAI/main/RemoveWindowsAi.ps1``& -nonInteractive -AllOptions -EnableLogging` |
| `win11debloat` | 下載 [Raphire/Win11Debloat](https://github.com/Raphire/Win11Debloat) `master.zip`、解壓、寫出 `unattend-config.json`(清單與 `windows-remote-toolkit/config/win11debloat-config.json` 同步)、跑 `Win11Debloat.ps1 -Silent -Config ... -NoRestartExplorer` |
| `remove-uwp-apps` | 依 `$UwpRemoveList`22 個 AppxPackageBingNews/BingWeather/Xbox*/MSTeams/Photos/...)逐個 `Remove-AppxPackage -AllUsers``Remove-AppxProvisionedPackage` |
| `install-telegram` | 下載 `https://telegram.org/dl/desktop/win64``/VERYSILENT /SUPPRESSMSGBOXES /NORESTART` |
| `cleanup-unattend-files` | 刪掉 `C:\Windows\Panther\unattend.xml``C:\Windows\Panther\Unattend\unattend.xml`(含明碼密碼) |
### `User` 帳號
- **用途**:給使用者日常使用,和部署用的管理員 `Admin` 分開。
- **建立**`unattend.xml` Order 3 直接 `net user User 1234 /add`(首字大寫一次到位,不在 Setup.ps1 改名)。
- **權限**:一般 `Users` 群組(非 Administrators。需要管理員權限時走 UAC`Admin/P@ssw0rd!`)。
- **首次登入強制改密**`/logonpasswordchg:yes` 會在下次登入時跳「密碼必須變更」。可以改成複雜密碼。
- **如果 `net user` 因為 Windows 密碼政策拒絕 `1234`**Order 3 會失敗但不會擋後面,手動於 PowerShell 以 `New-LocalUser`+更寬的密碼重跑。
### Order 4 的磁碟掃描沒找到 Setup.ps1 怎麼辦
Order 4 會逐個檢查所有掛載中的 FileSystem PSDrive`\ventoy\script\Setup.ps1`。沒找到就寫 `NOT FOUND``C:\Windows\Temp\firstlogon-copysetup.log`Order 5 接著用 `if exist` 判斷,找不到就寫 `SETUP_NOT_FOUND``firstlogon-runsetup.log` 然後跳過。原因通常是:
| 現象 | 原因 | 對策 |
|---|---|---|
| `NOT FOUND` | Ventoy USB 在 OOBE 完成前被拔掉 | 別拔,等 reboot 後再拔 |
| `NOT FOUND` | `Setup.ps1` 沒 cp 到 `/Volumes/Ventoy/ventoy/script/` | 重新 `cp` + `dot_clean` 後再插上重裝 |
| 找到但 Order 5 報 `Cannot run script ... not digitally signed` | 機器 ExecutionPolicy 是 Restricted | 不會發生Order 5 用 `-ExecutionPolicy Bypass` 強蓋 |
| 找到了但 Setup.ps1 早早 ERR | 看 `C:\Windows\Temp\setup.log``=== <name> ERR ===` 行 | 對照上面的段名表逐段重跑 |
### 排查 Setup.ps1 失敗
```powershell
notepad C:\Windows\Temp\firstlogon-copysetup.log # Order 4USB 掃描結果
notepad C:\Windows\Temp\firstlogon-runsetup.log # Order 5找不到 Setup.ps1 才會有
notepad C:\Windows\Temp\setup.log # Setup.ps1 主 log
```
`setup.log` 每段都有 `=== <name> START === ... === <name> DONE === ``=== <name> ERR: <msg> ===`。失敗段可以登入 `Admin` 後手動:
```powershell
powershell -ExecutionPolicy Bypass -File C:\Scripts\Setup.ps1
```
整支重跑(每段都是冪等的);或只挑某段:把 `Setup.ps1` 開起來,把那段 `Section '...'` 區塊的內容貼進 PowerShell 視窗即可。
### RemoveWindowsAI 補充
- **在做什麼**:跑 [zoicware/RemoveWindowsAI](https://github.com/zoicware/RemoveWindowsAI) 的 `RemoveWindowsAi.ps1`,一次把 Copilot系統EdgeOffice、Recall排程任務、Input Insights、AI Fabric、Click to Do、Paint 實驗、Voice Access、Gaming Copilot、Notepad Rewrite、Photos AI 等 AI 元件全數關掉或移除AppX、CBS、Registry、Group Policy 都會動)。
- **參數**`-nonInteractive`(不跳互動選單)+`-AllOptions`(全部選項都跑)+`-EnableLogging`(讓腳本自己也寫 log
- **執行時間**:視目標機速度,通常 30 秒3 分鐘。移除 CBS package 那段最慢。
- **抓的是 `main` 分支**:每次部署可能拿到不同版本。要鎖定版本就把 `Setup.ps1` 中對應 URL 的 `/main/` 換成 commit SHA。
- **可逆性**:腳本本身有 `-revertMode``-backupMode`,要還原的話可以登入後手動以 `-revertMode` 重跑;但 `-AllOptions` 跑完有些 CBS package 已被刪,`-revertMode` 不一定救得回,需要搭配 `-RunWinUpdateRepair` 從 Windows Update 重取。
- **風險面**移除「Nonremovable」AppX、刪 CBS package 屬於侵入性操作,可能導致未來 Windows Update 失敗或特定功能殘缺。部署前建議先在 VM 跑過一次。
### Telegram 補充
- **要有網路**OOBE 裡 `SkipMachineOOBE=true` 跳過了網路設定精靈,所以目標機必須有 Ethernet+DHCP或本身已記住 Wi-Fi。
- **網路等待上限 60 秒**`Setup.ps1` 開頭的 `wait-network` 跑一次 `Test-Connection 8.8.8.8` 迴圈,最多等 30 回合×2 秒ICMP 被擋住的環境會等完整 60 秒但 HTTPS 其實可用,也能跑下去。
- **per-user 安裝**Telegram 安裝程式預設裝到 Admin 這個帳號底下,**新建的 `User` 看不到**。要全機安裝就在 `Setup.ps1``install-telegram` 段把 `ArgumentList` 加上 `'/ALLUSERS'`
- **抓的是 latest 版**:每次部署抓當下最新版。要鎖版本改用 `https://updates.tdesktop.com/tsetup/tsetup-x64.X.Y.Z.exe` 直鏈。
---
## 本次部署已知限制
沿用 repo 預設值,下列情況會失敗,改用前要先處理:
- **目標機若是 BIOS/MBR**`<DiskConfiguration>` 目前寫死 UEFI+GPT分割階段會報錯。
- **ARM64 機器**:所有 `<component>``processorArchitecture="amd64"` 要改成 `arm64`;同時 `Setup.ps1` 內的 `OneDriveSetup.exe` SysWOW64 路徑、`winget` Chrome `--scope machine` 等部分行為要重驗。
- **Ventoy USB 在 reboot 前被拔掉**Order 4 會找不到 `Setup.ps1`13 段 post-install 全部 skip。請等到第二次重開機進到登入畫面後才拔。
- **密碼是明碼**`<PlainText>true</PlainText>`):僅適合測試用途;正式部署請用 Windows SIM 產 Base64。
- **Phase 2 全部需要外網**:目標機沒網路的話,從 `wait-network` 之後 7 段都會 ERRPhase 1 的 8 段防火牆、RDP、ICMP、WinRM、OneDrive 移除、Cortana 關閉、Default profile UI/IME、改名隱藏帳號仍會成功完成。
- **公開 KMS 啟用**`Setup.ps1` 預設用 `kms.digiboy.ir` 等第三方 KMS這對內網/正式環境不適合。把 `$InternalKmsServers` 改成你自己的 KMS 主機就好。