fix(kiosk): WESL class-level calls — first-boot reboot loop found in VM e2e #7

Merged
SilverLABS merged 1 commits from fix/kiosk-wesl-classlevel into main 2026-06-09 15:11:00 +00:00
Owner

VM e2e on VM 102 caught a first-boot reboot loop (the "Why did my PC restart?" OOBE screen), root-caused from the VM's own disk logs (silvermetal-firstboot.log + silvermetal-kiosk.log).

Root cause

Configure-Kiosk.ps1 configured Shell Launcher with Invoke-CimMethod -InputObject $wesl for SetDefaultShell/SetCustomShell. But WESL_UserSetting exposes static methods on the classGet-CimInstance returns no instance, so $wesl is null and those calls threw "Cannot bind argument to parameter 'InputObject' because it is null." Meanwhile the class-level SetEnabled($true) had already succeeded.

Net result: Shell Launcher enabled with no shell configured → every logon, including OOBE's defaultuser0, gets a broken shell → reboot loop.

Fix

  • Call SetEnabled / SetDefaultShell / SetCustomShell all class-level (-Namespace/-ClassName). Setting the default shell to explorer.exe is what keeps OOBE and normal logons alive; only sm-bootstrap gets the kiosk launcher.
  • Added GetCustomShell verification + a fail-open rollback: on any failure, SetEnabled($false) and drop a RunOnce launch of the Welcome app — so a WMI hiccup can never brick the box again (it degrades to a normal logon that still runs onboarding).
  • Same class-level correction applied to BootstrapService.RevertKioskAsync (its RemoveCustomShell was also instance-based and silently no-op'd).

Verification

  • Configure-Kiosk.ps1 parses; welcome solution builds, 29/29 tests pass.
  • Next: rebuild ISO (this PR's CI) → restage to VM 102 → fresh reinstall to confirm the kiosk + glass card + branded desktop.

🤖 Generated with Claude Code

**VM e2e on VM 102 caught a first-boot reboot loop** (the "Why did my PC restart?" OOBE screen), root-caused from the VM's own disk logs (`silvermetal-firstboot.log` + `silvermetal-kiosk.log`). ## Root cause `Configure-Kiosk.ps1` configured Shell Launcher with `Invoke-CimMethod -InputObject $wesl` for `SetDefaultShell`/`SetCustomShell`. But `WESL_UserSetting` exposes **static methods on the class** — `Get-CimInstance` returns no instance, so `$wesl` is `null` and those calls threw *"Cannot bind argument to parameter 'InputObject' because it is null."* Meanwhile the class-level `SetEnabled($true)` had **already succeeded**. Net result: **Shell Launcher enabled with no shell configured** → every logon, including OOBE's `defaultuser0`, gets a broken shell → reboot loop. ## Fix - Call `SetEnabled` / `SetDefaultShell` / `SetCustomShell` **all class-level** (`-Namespace`/`-ClassName`). Setting the default shell to `explorer.exe` is what keeps OOBE and normal logons alive; only `sm-bootstrap` gets the kiosk launcher. - Added `GetCustomShell` verification + a **fail-open rollback**: on any failure, `SetEnabled($false)` and drop a `RunOnce` launch of the Welcome app — so a WMI hiccup can never brick the box again (it degrades to a normal logon that still runs onboarding). - Same class-level correction applied to `BootstrapService.RevertKioskAsync` (its `RemoveCustomShell` was also instance-based and silently no-op'd). ## Verification - `Configure-Kiosk.ps1` parses; welcome solution builds, **29/29** tests pass. - Next: rebuild ISO (this PR's CI) → restage to VM 102 → fresh reinstall to confirm the kiosk + glass card + branded desktop. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
SilverLABS added 1 commit 2026-06-09 15:05:34 +00:00
fix(kiosk): call WESL_UserSetting methods class-level (was bricking first boot)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Successful in 4m45s
45939e1e9f
VM e2e caught a reboot loop: Configure-Kiosk used `Invoke-CimMethod -InputObject $wesl`
for SetDefaultShell/SetCustomShell, but WESL_UserSetting exposes STATIC methods and
Get-CimInstance returns null — so those calls threw "InputObject is null" while the
class-level SetEnabled($true) had already succeeded. Result: Shell Launcher enabled with
NO shell configured -> every logon (incl. OOBE defaultuser0) gets a broken shell -> the
"Why did my PC restart?" OOBE loop.

Fix: call SetEnabled/SetDefaultShell/SetCustomShell all class-level (-Namespace/-ClassName).
Setting the DEFAULT shell to explorer.exe is what keeps OOBE/normal logons alive; only
sm-bootstrap gets the kiosk launcher. Added GetCustomShell verification + a fail-open
rollback (SetEnabled false + RunOnce launch of the Welcome app) so a WMI hiccup can never
brick the box again. Same class-level fix applied to BootstrapService.RevertKioskAsync.

Found via VM 102 disk logs (silvermetal-firstboot.log + silvermetal-kiosk.log).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SilverLABS merged commit 863be56d15 into main 2026-06-09 15:11:00 +00:00
SilverLABS deleted branch fix/kiosk-wesl-classlevel 2026-06-09 15:11:00 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: SilverLABS/SilverMetal#7