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>
This commit is contained in:
2026-04-27 13:59:15 +08:00
parent c84e18bd9d
commit b1e5b6912a
7 changed files with 15 additions and 25 deletions

View File

@@ -44,7 +44,7 @@ There is no way to "run" this repo on the dev machine (macOS). All verification
- **`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.)
- **`Setup.ps1` is shipped via the Ventoy USB, not embedded in `unattend.xml`.** `FirstLogonCommands` Order 4 scans every mounted filesystem drive for `\ventoy\script\Setup.ps1` and copies the first match to `C:\Scripts\Setup.ps1`; Order 5 runs it. Two consequences: (1) the Ventoy USB **must remain plugged in until first logon completes** — yanking it after WinPE means Setup.ps1 never makes it to disk and the post-install steps silently skip (`C:\Windows\Temp\firstlogon-copysetup.log` will say `NOT FOUND`); (2) editing `Setup.ps1` in the repo is not enough — re-copy to `/Volumes/Ventoy/ventoy/script/Setup.ps1` before each test deploy. Both `firstlogon-copysetup.log` and `setup.log` live under `C:\Windows\Temp\`.
- **`Setup.ps1` runs as the AutoLogon `Admin` session** in `FirstLogonCommands`. It modifies the Default profile's `NTUSER.DAT` (loaded via `reg load HKU\SetupDefault C:\Users\Default\NTUSER.DAT`) to push UI/IME defaults to *future* user logins — it does **not** touch the AutoLogon `Admin` session itself, and it cannot reach the just-created `user`/`User` profile because that profile dir doesn't exist until that user first logs in. Anything you want applied to `Admin`'s already-active session has to go through `HKCU` directly.
- **The `user``User` rename happens inside `Setup.ps1`**, not in `unattend.xml`. `unattend.xml` Order 3 creates the lowercase `user` (so it's bulletproof even if `Setup.ps1` never runs); `Setup.ps1`'s `rename-hide-accounts` section then `Rename-LocalUser`s it to capitalised `User` and hides `Admin` from the login screen via `SpecialAccounts\UserList`. If you change the account name convention, both places must be edited.
- **The `User` account is created directly in `unattend.xml` Order 3** with capitalised name (`net user User 1234 /add`); there is no rename step. `Setup.ps1`'s `hide-admin-account` section only handles hiding `Admin` from the login screen via `SpecialAccounts\UserList\Admin=0`. If you change the account name convention, only `unattend.xml` Order 3 needs to change.
## When making changes

View File

@@ -122,7 +122,7 @@ cat /Volumes/Ventoy/ventoy/ventoy.json
|---|---|---|
| 1 | `net accounts /maxpwage:unlimited`(密碼永不過期) | 否 |
| 2 | `Rename-Computer` 把主機名改成 `PC-XXXXX`(重開後生效) | 否 |
| 3 | `net user user 1234 /add``/logonpasswordchg:yes`(建立一般使用者 `user`,首次登入強制改密;之後 Setup.ps1 會把它改名成 `User` | 否 |
| 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` 重開機 | 否 |
@@ -144,7 +144,7 @@ Order 4/5 是改版重點:把原本散在 `FirstLogonCommands` 裡的 OpenSSH
| `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 |
| `rename-hide-accounts` | `Rename-LocalUser user → User``SpecialAccounts\UserList\Admin=0`(從登入畫面隱藏 Admin |
| `hide-admin-account` | `SpecialAccounts\UserList\Admin=0`(從登入畫面隱藏 Admin;帳號仍存在仍可登入 |
**Phase 2需網路、最多等 60 秒):**
@@ -160,14 +160,13 @@ Order 4/5 是改版重點:把原本散在 `FirstLogonCommands` 裡的 OpenSSH
| `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` → `User` 帳號
### `User` 帳號
- **用途**:給使用者日常使用,和部署用的管理員 `Admin` 分開。
- **建立**`unattend.xml` Order 3 `net user user 1234 /add`(首字小寫)。
- **改名**`Setup.ps1``rename-hide-accounts` 段把 `user` 改成 `User`(首字大寫)。要先建小寫再改名是因為 `Rename-LocalUser` 必須對既有帳號操作;如果 `Setup.ps1` 沒跑完,最差情況是有個 `user` 還能登入。
- **建立**`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`+更寬的密碼重跑,再讓 `Setup.ps1` 改名
- **如果 `net user` 因為 Windows 密碼政策拒絕 `1234`**Order 3 會失敗但不會擋後面,手動於 PowerShell 以 `New-LocalUser`+更寬的密碼重跑。
### Order 4 的磁碟掃描沒找到 Setup.ps1 怎麼辦

View File

@@ -113,7 +113,7 @@ Ventoy 支援寫進 VHD/VDI可直接掛進 Hyper-V / VirtualBox 當第一顆
| 第一次重開 | 黑屏 → 「請稍候」 | 12 分鐘 |
| OOBE 略過 | **不該出現任何選單**;直接跳過 | 秒殺 |
| AutoLogon | 以 `Admin` 自動登入到桌面顯示名稱是「Administrator」 | — |
| FirstLogonCommands | 閃過一連串 PowerShell / cmd 黑視窗(密碼永不過期、改主機名、建 user 帳號、從 USB 拷 Setup.ps1、跑 Setup.ps1 的 13 段 post-install | 515 分鐘(含 FoD 下載、Win11Debloat 解壓、winget Chrome、AI 元件移除) |
| FirstLogonCommands | 閃過一連串 PowerShell / cmd 黑視窗(密碼永不過期、改主機名、建 `User` 帳號、從 USB 拷 Setup.ps1、跑 Setup.ps1 的 13 段 post-install | 515 分鐘(含 FoD 下載、Win11Debloat 解壓、winget Chrome、AI 元件移除) |
| 重開機 | 5 秒倒數後重啟 | — |
| 第二次開機 | 看到登入畫面,有 `User` 一個選項(`Admin` 已被 SpecialAccounts 隱藏;輸入帳號名仍可登入) | — |

View File

@@ -59,14 +59,14 @@ Windows Setup 在不同階段套用不同 `<settings pass="...">`
- `FirstLogonCommands` — 按 `Order` 依序執行:
1. `cmd.exe /c net accounts /maxpwage:unlimited`(密碼永不過期)
2. `Rename-Computer` 改主機名成 `PC-XXXXX`(重開後生效)
3. 建立本機帳號 `user`(密碼 `1234``net user /logonpasswordchg:yes` 強制首次登入改密;之後 `Setup.ps1` 會把它改名成 `User`
3. 建立本機帳號 `User`(密碼 `1234``net user /logonpasswordchg:yes` 強制首次登入改密)
4. 掃所有掛載中的 FileSystem PSDrive 找 `\ventoy\script\Setup.ps1`,複製到 `C:\Scripts\Setup.ps1`log 寫到 `C:\Windows\Temp\firstlogon-copysetup.log`
5.`C:\Scripts\Setup.ps1`13 段 post-install 詳見 `Setup.ps1``DEPLOY.md`log 寫到 `C:\Windows\Temp\setup.log`;找不到檔案時改寫 `firstlogon-runsetup.log` 並跳過)
6. `shutdown /r /t 5`(重開機)
### `Setup.ps1` 涵蓋的 13 段(首次登入由 Order 5 執行)
**Phase 1不需網路** SSH 22/TCP 防火牆、RDP+3389、ICMP Echo Inbound、WinRM`TrustedHosts=*`、OneDrive 解除安裝、Cortana/Web Search 關閉、Default profile 套 Dark mode顯示副檔名隱藏檔工作列靠左預設英數鍵盤停 IME 切換熱鍵、`user``User` 改名+從登入畫面隱藏 `Admin`
**Phase 1不需網路** SSH 22/TCP 防火牆、RDP+3389、ICMP Echo Inbound、WinRM`TrustedHosts=*`、OneDrive 解除安裝、Cortana/Web Search 關閉、Default profile 套 Dark mode顯示副檔名隱藏檔工作列靠左預設英數鍵盤停 IME 切換熱鍵、從登入畫面隱藏 `Admin`
**Phase 2需網路`wait-network` 後執行):** OpenSSH Server FoD、KMS 啟用(先試 `$InternalKmsServers` 再 fallback 公開 KMS、winget 裝 Chrome、`zoicware/RemoveWindowsAI -AllOptions``Raphire/Win11Debloat -Silent -Config`、22 個 UWP AppxPackage 移除(與 `windows-remote-toolkit/config/remove-apps-config.json` 同步、Telegram 靜默安裝、刪 `C:\Windows\Panther\unattend.xml` 殘留。

View File

@@ -46,7 +46,7 @@ XML 能做的事有上限。超過這條線(裝軟體、設 Registry、拉 Git
```
Order 1 → net accounts (一行搞定的雜事直接 cmd密碼永不過期
Order 2 → Rename-Computer (主機名改 PC-XXXXX重開後生效
Order 3 → net user user 1234 /add (建立一般使用者,強制首次登入改密)
Order 3 → net user User 1234 /add (建立一般使用者 User,強制首次登入改密)
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 生效)
@@ -63,7 +63,7 @@ winrm-enable → Enable-PSRemoting + winrm quickconfig + Tru
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-accountsuser → User從登入畫面隱藏 Admin
hide-admin-account → 從登入畫面隱藏 Admin(帳號仍存在仍可用)
[Phase 2需要網路]
wait-network → 等 ICMP 通到 8.8.8.8,上限 60 秒
@@ -81,8 +81,6 @@ cleanup-unattend-files → 刪 C:\Windows\Panther\unattend.xml
> 為什麼把 `Setup.ps1` 放在 Ventoy USB 上、不直接 base64 內嵌進 `unattend.xml`(1) `unattend.xml` 仍是 Windows SIM 可驗證的純 schema XML(2) `Setup.ps1` 改完只要 `cp` 一次就更新,不用重 escape(3) 每段 `Section` 寫到 `setup.log` 才方便排查。代價是USB 必須留到第一次登入完成才能拔。
>
> 為什麼是「先建小寫 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。
---

View File

@@ -233,15 +233,8 @@ Section 'apply-ui-ime-default-profile' {
}
}
Section 'rename-hide-accounts' {
$u = Get-LocalUser -Name 'user' -ErrorAction SilentlyContinue
if ($u -and $u.Name -ceq 'user') {
Rename-LocalUser -Name 'user' -NewName 'User'
Log 'Renamed user -> User'
} else {
Log "Local user 'user' not found or already renamed; skip"
}
Section 'hide-admin-account' {
# 帳號 User 在 unattend.xml Order 3 已直接以大寫建立,這裡只負責把 Admin 從登入畫面藏掉
$userListKey = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList'
Set-RegValue $userListKey 'Admin' 0 # 0 = 從登入畫面隱藏(帳號仍存在仍可用)
}

View File

@@ -169,8 +169,8 @@
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>cmd.exe /c "net user user 1234 /add &amp; net user user /logonpasswordchg:yes"</CommandLine>
<Description>建立本機帳號 user密碼 1234首次登入強制改密;之後 Setup.ps1 會把它改名成 User</Description>
<CommandLine>cmd.exe /c "net user User 1234 /add &amp; net user User /logonpasswordchg:yes"</CommandLine>
<Description>建立本機帳號 User密碼 1234首次登入強制改密</Description>
<RequiresUserInput>false</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">