新增 Setup.ps1(13 段 post-install);FirstLogonCommands 改從 Ventoy USB 拷腳本

把分散在 unattend.xml inline 的網路相依步驟(OpenSSH/Telegram/RemoveAI)和
新加入的 10 個 post-install 動作整合進獨立的 Setup.ps1,由 FirstLogonCommands
Order 4 從 Ventoy USB(/ventoy/script/Setup.ps1)掃磁碟複製到 C:\Scripts\,
Order 5 執行。腳本分兩 phase:

Phase 1(不需網路):SSH 22 防火牆、RDP+3389、ICMP Echo、WinRM TrustedHosts=*、
移 OneDrive、關 Cortana/WebSearch、套 UI/IME 預設到 Default profile、user→User
改名 + 從登入畫面隱藏 Admin。

Phase 2(要網路,wait-network 後):OpenSSH Server FoD、KMS 啟用(先試
$InternalKmsServers 後 fallback 公開 KMS)、winget Chrome、RemoveWindowsAI、
Win11Debloat、22 個 UWP 移除、Telegram、刪 Panther 殘留。

每段以 Section 包裝寫獨立 START/DONE/ERR 到 C:\Windows\Temp\setup.log,方便逐段
重跑與排查。

文件全部同步:DEPLOY/QUICKSTART/SUMMARY/README/CLAUDE 都加上 Setup.ps1 的
USB 部署、cp 步驟、Order 表、排查指引。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 13:36:13 +08:00
parent b3329d4889
commit c84e18bd9d
7 changed files with 565 additions and 108 deletions

View File

@@ -44,20 +44,46 @@ XML 能做的事有上限。超過這條線(裝軟體、設 Registry、拉 Git
`FirstLogonCommands` 就是交棒點:
```
Order 1 → Setup.ps1 所有「後續設定」的預留入口
Order 2 → net accounts 一行搞定的雜事直接 cmd
Order 3 → Rename-Computer (主機名改 PC-XXXXX重開後生效
Order 4 → net user user 1234 /add (建立一般使用者,強制首次登入改密
Order 5 → Add-WindowsCapability OpenSSH (等網路→安裝並啟動 sshd
Order 6 → Telegram 靜默安裝 (等網路→下載 tsetup.exe + /VERYSILENT
Order 7 → shutdown /r (重開機收尾,讓 rename 生效)
Order 1 → net accounts 一行搞定的雜事直接 cmd密碼永不過期
Order 2 → Rename-Computer 主機名改 PC-XXXXX重開後生效
Order 3 → net user user 1234 /add (建立一般使用者,強制首次登入改密
Order 4 → Copy Setup.ps1 from Ventoy USB (掃磁碟找 \ventoy\script\Setup.ps1 → C:\Scripts\
Order 5 → powershell -File Setup.ps1 13 段 post-install看下表
Order 6 → shutdown /r (重開機收尾,讓 rename 生效
```
這讓 `unattend.xml` 保持「只負責 Windows 本身的安裝」,其他事情外包給腳本。職責分離之後,改軟體清單不需要動 XML改部署流程也不需要動 Setup 邏輯。
`Setup.ps1` 內部分兩個 phase用空的 `wait-network` 段切開):
> Order 5、6OpenSSH、Telegram是「交棒到腳本」這條原則的例外**單一套件、需求穩定**的情況下,直接在 `FirstLogonCommands` 裡下載安裝比起硬塞進 `Setup.ps1` 單純。一旦要裝的東西變成清單3+ 個套件、要版本鎖定、要錯誤處理),就該整批移進 `Setup.ps1` 或改用 winget/choco。
```
[Phase 1本機設定不需網路]
firewall-ssh-22 → SSH 22/TCP inbound 防火牆規則
rdp-enable-3389 → 啟用 RDP + 3389 防火牆群組
icmp-echo-allow → ICMPv4 Echo Request inbound外部 ping 得到)
winrm-enable → Enable-PSRemoting + winrm quickconfig + TrustedHosts=*
onedrive-remove → /uninstall + 清啟動鍵 + 移除 CLSID
cortana-websearch-off → AllowCortana=0、DisableWebSearch=1、SearchBoxSuggestions=1
apply-ui-ime-default-profile → reg load Default profile套 Dark mode / 工作列靠左 / 顯示副檔名 / 預設英數鍵盤 / 停 IME 切換熱鍵
rename-hide-accounts → user → User從登入畫面隱藏 Admin
[Phase 2需要網路]
wait-network → 等 ICMP 通到 8.8.8.8,上限 60 秒
openssh-server-install → Add-WindowsCapability OpenSSH.Server + Start-Service sshd
kms-activate → 試 $InternalKmsServers → $PublicKmsServers第一個 successful 就停
winget-install-chrome → winget install Google.Chrome --silent --scope machine
remove-windows-ai → irm zoicware/RemoveWindowsAI | iex -nonInteractive -AllOptions
win11debloat → 下載 Raphire/Win11Debloat → -Silent -Config
remove-uwp-apps → 22 個 AppxPackageBingNews、Xbox*、MSTeams、Photos…
install-telegram → 下載 telegram.org/dl/desktop/win64 + /VERYSILENT
cleanup-unattend-files → 刪 C:\Windows\Panther\unattend.xml清明碼密碼殘留
```
這讓 `unattend.xml` 保持「只負責 Windows 本身的安裝+簡單到不會壞的 cmd」其他事情外包給 `Setup.ps1`。職責分離之後,改軟體清單不需要動 XML改部署流程也不需要動 Setup 邏輯。
> 為什麼把 `Setup.ps1` 放在 Ventoy USB 上、不直接 base64 內嵌進 `unattend.xml`(1) `unattend.xml` 仍是 Windows SIM 可驗證的純 schema XML(2) `Setup.ps1` 改完只要 `cp` 一次就更新,不用重 escape(3) 每段 `Section` 寫到 `setup.log` 才方便排查。代價是USB 必須留到第一次登入完成才能拔。
>
> Order 5、6 共用「等 ICMP 通到 8.8.8.8、最多 60 秒」的網路等待迴圈,並且各自把結果寫到 `C:\Windows\Temp\firstlogon-*.log`,避免前一輪 Telegram 無聲失敗的情況再發生
> 為什麼是「先建小寫 user 再改 User」`unattend.xml` 的 `net user user 1234 /add` 鐵打不會壞;`Setup.ps1` 的 `Rename-LocalUser` 萬一沒跑完,最差結果是有個小寫 `user` 還能登入。先建後改 = bulletproof
>
> `remove-windows-ai` 跑的是 `main` 分支的腳本,**每次部署抓的版本可能不同**。要確定性、可稽核的部署,把 `Setup.ps1` 中對應 URL 的 `/main/` 換成 commit SHA。
---
@@ -85,7 +111,8 @@ Windows Setup 有七個 pass本檔只用三個。不是偷懶是**三個 p
| **本機帳號 + AutoLogon** | 純離線可跑 | 改成 Domain Join + 網域管理員登入 |
| **ProtectYourPC=3** | 略過 OOBE 的隱私頁,預設行為 | 依公司政策調整,或用 GPO 蓋掉 |
| **單一 Disk 0 + 整碟清空** | 對測試 VM 最安全的假設 | 多硬碟環境要加 `DiskID` 判斷邏輯 |
| **`Setup.ps1` 路徑硬寫 C:\Scripts\** | 簡單 | 改從 USB/網路拉,或用 MDT 的 `Applications` 機制 |
| **`Setup.ps1` 用磁碟掃描從 Ventoy USB 拷貝** | 不需要架網路服務、跨網段也能跑、USB 拔掉也能在現場補救 | 內部 IT 場合改用 SCCM/Intune 派送,或乾脆 base64 內嵌進 XML 拿到完全自包含 |
| **`$PublicKmsServers` 用第三方 KMS** | 沒授權主機也能跑通 | 把 `$InternalKmsServers` 改成自家 KMS 主機,公開那串不再被 fallback |
這些不是 bug是**當前脈絡下的合理起點**。要產品化就對照這張表一個一個升級。