From 22e002d444404c46274e14de1b9931047e3b0e4b Mon Sep 17 00:00:00 2001 From: Timmy Date: Tue, 28 Apr 2026 08:52:29 +0800 Subject: [PATCH] =?UTF-8?q?07-apply-ui-ime-default-profile=EF=BC=9A?= =?UTF-8?q?=E9=99=A4=E4=BA=86=20Default=20profile=20=E4=B9=9F=E5=A5=97?= =?UTF-8?q?=E5=88=B0=E6=89=80=E6=9C=89=E5=B7=B2=E8=BC=89=E5=85=A5=E7=9A=84?= =?UTF-8?q?=E7=9C=9F=E4=BA=BA=20user=20hive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前只寫 Default profile NTUSER.DAT,新使用者首次登入會繼承—— 但若腳本是在 User 已登入後才被重跑(例如 deploy 後想改設定), Default 改動不會反映到既存的 User profile,肉眼看不到變化。 把套設定的邏輯抽成 Apply-UiImeSettings function,先寫 Default、 再用 Win32_UserProfile 列出所有非系統 profile,凡是 hive 已載入 (HKEY_USERS\ 存在)的就一併寫進去。production 流程下 User 還沒建立、所以只有 Admin 拿到(無關緊要 Admin 會被隱藏); re-run 時 User hive 已載入則直接生效。 --- steps/07-apply-ui-ime-default-profile.ps1 | 114 +++++++++++++--------- 1 file changed, 68 insertions(+), 46 deletions(-) diff --git a/steps/07-apply-ui-ime-default-profile.ps1 b/steps/07-apply-ui-ime-default-profile.ps1 index b0239e1..7bbdc08 100644 --- a/steps/07-apply-ui-ime-default-profile.ps1 +++ b/steps/07-apply-ui-ime-default-profile.ps1 @@ -1,59 +1,81 @@ . "$PSScriptRoot\_common.ps1" -# 把 UI / IME 預設套到 Default profile,新使用者首次登入會繼承 +# Apply UI/IME settings to (a) Default profile NTUSER.DAT (so brand-new users +# inherit) and (b) every currently-loaded real-user hive (so re-runs against +# an already-logged-in box still take effect immediately on those users). +function Apply-UiImeSettings { + param([string]$base) # e.g. "Registry::HKU\SetupDefault" or "Registry::HKEY_USERS\" + + $adv = "$base\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" + Set-RegValue $adv 'HideFileExt' 0 + Set-RegValue $adv 'Hidden' 1 + Set-RegValue $adv 'TaskbarAl' 0 + Set-RegValue $adv 'ShowTaskViewButton' 0 + Set-RegValue $adv 'LaunchTo' 1 + Set-RegValue $adv 'Start_TrackProgs' 0 + + $theme = "$base\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" + Set-RegValue $theme 'AppsUseLightTheme' 0 + Set-RegValue $theme 'SystemUseLightTheme' 0 + + $search = "$base\Software\Microsoft\Windows\CurrentVersion\Search" + Set-RegValue $search 'SearchboxTaskbarMode' 0 + + # SearchSettings 在某些 build 上 reg.exe 會「存取被拒」(Win11Debloat 的 + # Disable_Search_History.reg 跟 Disable_Search_Highlights.reg 都會撞), + # 但 PowerShell .NET API 寫得進去——這裡一次處理掉,Win11Debloat config 已把這兩項移除 + $searchSettings = "$base\Software\Microsoft\Windows\CurrentVersion\SearchSettings" + Set-RegValue $searchSettings 'IsDeviceSearchHistoryEnabled' 0 + Set-RegValue $searchSettings 'IsDynamicSearchBoxEnabled' 0 + + $cloud = "$base\Software\Policies\Microsoft\Windows\CloudContent" + Set-RegValue $cloud 'DisableSpotlightCollectionOnDesktop' 1 + Set-RegValue $cloud 'DisableWindowsSpotlightFeatures' 1 + + # 鍵盤排序:英文鍵盤排第一(預設英數),注音排第二 + $kbPre = "$base\Keyboard Layout\Preload" + Set-RegValue $kbPre '1' '00000409' 'String' + Set-RegValue $kbPre '2' '00000404' 'String' + + # CHT 注音:預設英數模式、關掉雲端候選與預測 + $cht = "$base\Software\Microsoft\InputMethod\Settings\CHT" + Set-RegValue $cht 'Enable Default Input Mode' 0 + Set-RegValue $cht 'Enable Cand Predict' 0 + Set-RegValue $cht 'Enable Cloud Cand' 0 + Set-RegValue $cht 'Enable Cloud Input' 0 + + # 把系統 Hotkey 切換鍵停掉(3 = 不指定鍵) + $tg = "$base\Keyboard Layout\Toggle" + Set-RegValue $tg 'Hotkey' '3' 'String' + Set-RegValue $tg 'Language Hotkey' '3' 'String' + Set-RegValue $tg 'Layout Hotkey' '3' 'String' +} + Section 'apply-ui-ime-default-profile' { + # (a) Default profile(新使用者首次登入會繼承) $hivePath = 'C:\Users\Default\NTUSER.DAT' $mountKey = 'HKU\SetupDefault' reg.exe load $mountKey $hivePath | Out-Null try { - $base = "Registry::$mountKey" - - $adv = "$base\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" - Set-RegValue $adv 'HideFileExt' 0 - Set-RegValue $adv 'Hidden' 1 - Set-RegValue $adv 'TaskbarAl' 0 - Set-RegValue $adv 'ShowTaskViewButton' 0 - Set-RegValue $adv 'LaunchTo' 1 - Set-RegValue $adv 'Start_TrackProgs' 0 - - $theme = "$base\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" - Set-RegValue $theme 'AppsUseLightTheme' 0 - Set-RegValue $theme 'SystemUseLightTheme' 0 - - $search = "$base\Software\Microsoft\Windows\CurrentVersion\Search" - Set-RegValue $search 'SearchboxTaskbarMode' 0 - - # SearchSettings 這個 key 在某些 build 上 reg.exe import/add 會被「存取被拒」 - # (Win11Debloat 的 Disable_Search_History.reg 跟 Disable_Search_Highlights.reg 都會撞), - # 但 PowerShell 的 .NET API 寫得進去——所以這裡一次處理掉,Win11Debloat config 已把這兩項移除 - $searchSettings = "$base\Software\Microsoft\Windows\CurrentVersion\SearchSettings" - Set-RegValue $searchSettings 'IsDeviceSearchHistoryEnabled' 0 - Set-RegValue $searchSettings 'IsDynamicSearchBoxEnabled' 0 - - $cloud = "$base\Software\Policies\Microsoft\Windows\CloudContent" - Set-RegValue $cloud 'DisableSpotlightCollectionOnDesktop' 1 - Set-RegValue $cloud 'DisableWindowsSpotlightFeatures' 1 - - # 鍵盤排序:英文鍵盤排第一(預設英數),注音排第二 - $kbPre = "$base\Keyboard Layout\Preload" - Set-RegValue $kbPre '1' '00000409' 'String' - Set-RegValue $kbPre '2' '00000404' 'String' - - # CHT 注音:預設英數模式、關掉雲端候選與預測 - $cht = "$base\Software\Microsoft\InputMethod\Settings\CHT" - Set-RegValue $cht 'Enable Default Input Mode' 0 - Set-RegValue $cht 'Enable Cand Predict' 0 - Set-RegValue $cht 'Enable Cloud Cand' 0 - Set-RegValue $cht 'Enable Cloud Input' 0 - - # 把系統 Hotkey 切換鍵停掉(3 = 不指定鍵) - $tg = "$base\Keyboard Layout\Toggle" - Set-RegValue $tg 'Hotkey' '3' 'String' - Set-RegValue $tg 'Language Hotkey' '3' 'String' - Set-RegValue $tg 'Layout Hotkey' '3' 'String' + Apply-UiImeSettings "Registry::$mountKey" + Log "Applied to Default profile" } finally { [GC]::Collect() Start-Sleep 1 reg.exe unload $mountKey | Out-Null } + + # (b) 已載入的真人 user hive(HKU\,跳過 .DEFAULT / 系統 SID) + # 取自 Win32_UserProfile,過濾 Special;只在 hive 已載入時寫 + $profiles = Get-CimInstance Win32_UserProfile -ErrorAction SilentlyContinue | + Where-Object { -not $_.Special } + foreach ($p in $profiles) { + $sid = $p.SID + if (Test-Path "Registry::HKEY_USERS\$sid") { + Apply-UiImeSettings "Registry::HKEY_USERS\$sid" + Log ("Applied to live user hive {0} ({1})" -f $sid, (Split-Path $p.LocalPath -Leaf)) + } else { + Log ("Skip {0} ({1}) - hive not loaded" -f $sid, (Split-Path $p.LocalPath -Leaf)) + } + } }