把 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>
14 KiB
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 會做什麼:
{
"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 文件明確說不支援\n,換行會被一律忽略。要多行提示只能靠縮寫或另加 plugin(如menu_alias)。
重新部署步驟(macOS)
插入 Ventoy USB 後:
# 從 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
驗證:
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 時要改什麼
- 把新 ISO 丟到 USB 根目錄。
- 編輯
/Volumes/Ventoy/ventoy/ventoy.json,把對應條目的image換成新檔名(或新增一條)。 - 不用動
/Volumes/Ventoy/ventoy/script/unattend.xml與Setup.ps1,除非要改 Windows 版本特有設定。 - 若 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 master.zip、解壓、寫出 unattend-config.json(清單與 windows-remote-toolkit/config/win11debloat-config.json 同步)、跑 Win11Debloat.ps1 -Silent -Config ... -NoRestartExplorer |
remove-uwp-apps |
依 $UwpRemoveList(22 個 AppxPackage:BingNews/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.xmlOrder 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 失敗
notepad C:\Windows\Temp\firstlogon-copysetup.log # Order 4:USB 掃描結果
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 -ExecutionPolicy Bypass -File C:\Scripts\Setup.ps1
整支重跑(每段都是冪等的);或只挑某段:把 Setup.ps1 開起來,把那段 Section '...' 區塊的內容貼進 PowerShell 視窗即可。
RemoveWindowsAI 補充
- 在做什麼:跑 zoicware/RemoveWindowsAI 的
RemoveWindowsAi.ps1,一次把 Copilot(系統+Edge+Office)、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.exeSysWOW64 路徑、wingetChrome--scope machine等部分行為要重驗。 - Ventoy USB 在 reboot 前被拔掉:Order 4 會找不到
Setup.ps1,13 段 post-install 全部 skip。請等到第二次重開機進到登入畫面後才拔。 - 密碼是明碼(
<PlainText>true</PlainText>):僅適合測試用途;正式部署請用 Windows SIM 產 Base64。 - Phase 2 全部需要外網:目標機沒網路的話,從
wait-network之後 7 段都會 ERR;Phase 1 的 8 段(防火牆、RDP、ICMP、WinRM、OneDrive 移除、Cortana 關閉、Default profile UI/IME、改名隱藏帳號)仍會成功完成。 - 公開 KMS 啟用:
Setup.ps1預設用kms.digiboy.ir等第三方 KMS,這對內網/正式環境不適合。把$InternalKmsServers改成你自己的 KMS 主機就好。