diff --git a/windows/installer/oem/Configure-Kiosk.ps1 b/windows/installer/oem/Configure-Kiosk.ps1 index 2735ac3..73dbf8b 100644 --- a/windows/installer/oem/Configure-Kiosk.ps1 +++ b/windows/installer/oem/Configure-Kiosk.ps1 @@ -24,11 +24,29 @@ Log 'configuring onboarding lockdown (Explorer shell + policy)' # --- Keyboard Filter: block shell/escape hotkeys for the locked-down session --- Enable-WindowsOptionalFeature -Online -FeatureName Client-KeyboardFilter -NoRestart -ErrorAction SilentlyContinue | Out-Null $kf='root\standardcimv2\embedded' +# CRITICAL: by default the Keyboard Filter EXEMPTS administrators, and sm-bootstrap is an +# admin -> Win/Start/etc. were NOT blocked. Turn that exemption off so the filter applies. +$adm=Get-CimInstance -Namespace $kf -ClassName WEKF_Settings -Filter "Name='DisableKeyboardFilterForAdministrators'" -ErrorAction SilentlyContinue +if($adm){ $adm.Value='false'; Set-CimInstance -InputObject $adm -ErrorAction SilentlyContinue } foreach($combo in 'Win','Win+L','Ctrl+Esc','Ctrl+Win+F','Win+R','Alt+Tab','Ctrl+Shift+Esc','Alt+F4'){ $p=Get-CimInstance -Namespace $kf -ClassName WEKF_PredefinedKey -Filter "Id='$combo'" -ErrorAction SilentlyContinue if($p){ $p.Enabled=$true; Set-CimInstance -InputObject $p -ErrorAction SilentlyContinue } } -Log 'keyboard filter rules enabled' +Log 'keyboard filter rules enabled (admins included)' + +# --- Hide the taskbar for the locked-down session (auto-hide in the default-user hive, +# which the sm-bootstrap profile inherits). The fullscreen wizard covers it, but +# auto-hide stops it peeking. StuckRects3 byte 8: 0x03 = auto-hide on. --- +try { + & reg load 'HKLM\SM_DU_TB' 'C:\Users\Default\NTUSER.DAT' 2>$null | Out-Null + $sr='HKLM:\SM_DU_TB\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3' + New-Item $sr -Force | Out-Null + $bytes=[byte[]](0x30,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) + Set-ItemProperty $sr -Name 'Settings' -Value $bytes -Type Binary +} catch {} finally { [gc]::Collect(); Start-Sleep -Milliseconds 300; & reg unload 'HKLM\SM_DU_TB' 2>$null | Out-Null } +Log 'taskbar auto-hide set for default user' # --- escape policies (machine-wide; reverted at teardown) --- $sys='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' diff --git a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs index 8f1dff5..67de81d 100644 --- a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs +++ b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BootstrapService.cs @@ -40,7 +40,10 @@ public sealed class BootstrapService(IProcessRunner runner) : IBootstrapService // you're logged in as), THEN defer the real removal to a SYSTEM startup task that // runs on next boot, when sm-bootstrap is no longer logged on. It removes the // account + profile, then unregisters itself. - await Ps($"Remove-LocalUser -Name '{u}' -EA SilentlyContinue", ct); + // Disable immediately (in-session, takes effect at once so the account is unusable + // and shows as disabled), then best-effort delete; the deferred task does the real + // delete on next boot when it isn't logged on. + await Ps($"Disable-LocalUser -Name '{u}' -EA SilentlyContinue; Remove-LocalUser -Name '{u}' -EA SilentlyContinue", ct); var cleanup = $"Remove-LocalUser -Name '{u}' -ErrorAction SilentlyContinue; " + $"Get-CimInstance Win32_UserProfile | Where-Object {{ $_.LocalPath -like '*\\{u}' }} | Remove-CimInstance -ErrorAction SilentlyContinue; " +