Prevent WDAGUtilityAccount password expiration in new baselines - #6
Conversation
Co-authored-by: rkttu <1297346+rkttu@users.noreply.github.com>
Co-authored-by: rkttu <1297346+rkttu@users.noreply.github.com>
…utility-account-password-expiration # Conflicts: # src/MacSandbox/Core/UnattendBuilder.swift Co-authored-by: rkttu <1297346+rkttu@users.noreply.github.com>
|
|
There was a problem hiding this comment.
🟡 Changes recommended
The provisioning command currently embeds the password unquoted (brittle for future credential formats) and the architecture docs contain a now-inaccurate firewall description.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates Windows baseline provisioning so the internal WDAGUtilityAccount password does not expire (preventing long-lived baselines from failing automatic RDP logon), and documents the required rebuild for existing baselines.
Changes:
- Replace global password-age policy changes with account-scoped
Set-LocalUser -PasswordNeverExpires $trueduring OOBE provisioning. - Add a readiness marker + gated shutdown to avoid finalizing a baseline when account provisioning fails (accounting for
FirstLogonCommandsconcurrency). - Document that provisioning changes do not retrofit existing baselines and users must rebuild.
File summaries
| File | Description |
|---|---|
| src/MacSandbox/Core/UnattendBuilder.swift | Implements account-scoped non-expiring password configuration and gates baseline shutdown on a provisioning-ready marker. |
| docs/help.md | Documents that users must rebuild baselines to pick up provisioning improvements (including non-expiring WDAGUtilityAccount password). |
| ARCHITECTURE.md | Updates provisioning flow documentation to include PasswordNeverExpires gating behavior. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| let accountReadyMarker = "C:\\ProgramData\\MacSandbox-WDAGUtilityAccount.ready" | ||
| let accountSetupCommand = """ | ||
| $ErrorActionPreference = 'Stop' | ||
| & net.exe user WDAGUtilityAccount \(rdpPassword) | ||
| if ($LASTEXITCODE -ne 0) { throw 'Could not set the WDAGUtilityAccount password.' } | ||
| Set-LocalUser -Name 'WDAGUtilityAccount' -PasswordNeverExpires $true | ||
| Set-Content -LiteralPath '\(accountReadyMarker)' -Value 'ready' -Encoding Ascii | ||
| """ |
| bootstrap admin auto-logon → FirstLogonCommands enable the built-in **WDAGUtilityAccount**, set its RDP credential, | ||
| disable password expiration for that account, and **enable the RDP server** (`fDenyTSConnections=0`, NLA off, `LimitBlankPasswordUse=0`, | ||
| allow the firewall remote-desktop group) + configure the logon agent (Run key) → `shutdown` → baseline complete (status=ready). |
Long-lived baselines could stop automatic RDP logon when
WDAGUtilityAccountreached the Windows password-age limit. Existing baselines require rebuilding to receive the corrected account configuration.Account provisioning
Failure handling
FirstLogonCommandsexecution by waiting for readiness before finalization.Migration