Add win-add-temp-user - #152
Edwin Bernal Microsoft (EdwinBernal1) merged 6 commits into
Conversation
Adds a local administrator to an offline Windows disk using the Setup CmdLine hook, then boots the disk in the nested Hyper-V guest so the account is really created, and verifies that it exists.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cf64bab1-6099-4e7e-aef4-57ffea10ce6b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cf64bab1-6099-4e7e-aef4-57ffea10ce6b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cf64bab1-6099-4e7e-aef4-57ffea10ce6b
Automated review using the supplied PR Review AgentReviewed head: b2814df9f55c0e915423c260e1cd43949f69dea7 This is the supplied agent's static analysis, not a maintainer decision or a fresh repair/boot test. Findings have not been independently reproduced. No source or Azure resources were changed during review. The original report is retained locally; only leading process narration and local prompt-path provenance were normalized for posting. Finding text is unchanged. Full automated review reportPR Review: #152 — Add win-add-temp-userGenerated: 2026-09-10
Reviewed against the pinned head snapshot only. Helper contracts consulted: Standards baseline passes. The script sources FindingsCritical
Warning
Info
Operational Risk Assessment
Overall Risk: High 🔴 — driven by Critical 1 (a ~22%-per-run silent wrong-password outcome reported as success), Critical 3 (an unrollbackable privilege grant to an account the operator did not target), and the destructive-operation profile on a customer OS disk. ValidationDeterministic checks below were performed by the launcher and recorded in the review packet; the source assessment is this review's own.
Recommendationrequest changes The design is a genuine advance on The three Critical findings should be resolved before merge. Critical 1 is the priority: it is unconditional, quantified at roughly one run in five, introduced by this PR relative to the comparator's generator, and silent — both of the script's verification signals still report success. Criticals 2 and 3 share a precondition (the detect-time SAM read failing, which the script treats as a warning at 784-787) and are best fixed together, by gating the payload's group/enable commands on Because Critical 1 is probabilistic, the fixes should be validated by a targeted test — assert the exact password string round-trips through the generated This is an automated review produced by the |
…ery state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cf64bab1-6099-4e7e-aef4-57ffea10ce6b
Review findings implemented and exercisedPublication head: ea46b96325dbaea9400131840b03d13c94f7cbe5 The earlier automated report remains a static review of
Additional confirmed recovery gaps were fixed alongside these findings: strict existing Actual product testing: randomly selected Windows Server 2016/build 14393 and The tested script is byte-identical to candidate Original review provenance
|
Edwin Bernal Microsoft (EdwinBernal1)
left a comment
There was a problem hiding this comment.
Reviewed the current head after the earlier credential and recovery findings were addressed. Password generation is cryptographic, supplied input is constrained for the batch transport, generated credentials are kept out of the desktop log, and a failed account creation cannot promote an existing account. Success requires a complete guest result, while hook restoration and payload cleanup are verified with recovery metadata retained on failure. The catalog entry is consistent. I found no new blocking issue.
Residual validation gap: only the CLA check is reported by GitHub. This was a static review; I did not independently rerun the nested Hyper-V account-creation and recovery scenarios.
|
Tip ✅ APPROVE — Overall Score 90/100 (Grade A)WS2022-Gen2 end-to-end validation is clean, and closes the exact coverage gap flagged in the PR body ("These runs do not establish fresh password/RDP authentication, Gen2, BitLocker or domain-joined coverage"). All security invariants held on a real live repair; the generated password authenticates via VMRepair Script Test Report: win-add-temp-user.ps1Script under test: SummaryOverall Score: 90/100 (Grade: A) — APPROVE Ready to merge after the PR author's own maintainer review.
Fault Injection Results
Testing PerformedStrategy: breaker-integrated, real live cycle with
Execution Timeline
Convention AuditPSScriptAnalyzer
VMRepair Conventions
Security Invariants
Opportunities for Improvement10 points recoverable (current 90 → potential 100). None are blocking for PR #152.
How to Reach 100/100
Validation EvidenceBefore (broken — labowner disabled by breaker): After (repaired — azrepairadmin created, labowner still disabled): {
"azrepairadmin_present": true,
"azrepairadmin_enabled": true,
"azrepairadmin_in_admins": true,
"azrepairadmin_in_rdu": true,
"admin_group_members": [
"srcvm-ws22-g2\\azrepairadmin",
"srcvm-ws22-g2\\labowner"
],
"rdu_group_members": [
"srcvm-ws22-g2\\azrepairadmin"
],
"labowner_present": true,
"labowner_enabled": false,
"setup_type": 0,
"setup_cmdline": "",
"file_payload_present": false,
"file_result_present": false,
"file_manifest_present": false
}Guest-reported payload result (from Script self-reported completion (from Authentication proofs (LogonUser P/Invoke,
Condensed stdout: Review Checklist
Test Artifacts
No credentials retained in any artifact. No SME work item is tracked for this PR — all findings above are inlined; raw artifacts live in this workspace at the paths listed. Generated by VMRepairMint Script Testing sub-agent | Head SHA validated: |
511d3e2
into
Azure:main
What this adds
win-add-temp-user: one scenario script and its ownmap.jsonentry. Windows creates therequested local administrator during a nested boot using
SYSTEM\Setup\CmdLine; the scriptdoes not edit SAM structures or depend on Group Policy startup scripts.
Success requires a complete guest result for the requested account confirming creation,
administrator membership and enablement, with no contradictory readable SAM observation.
SAM presence alone is never proof that this run created the account. If account creation
fails, the payload does not promote or enable an existing account.
Recovery and safety
expansion. Printable ASCII passwords are supported except double quotes; unsupported
characters are rejected rather than silently changed by ASCII encoding.
unreadable manifest or pre-existing nonzero SetupType blocks a new operation.
an error and preserves recovery information instead of reporting success.
drive path after failed rediscovery; recovery instructions require stopping a managed guest.
Generated passwords are delivered in run output, not the scenario's desktop log. Azure Run
Command and the CLI can retain that output; handle it as sensitive. A supplied password is
not echoed by the scenario.
Parameters
usernameazrepairadmin. An existing account is not modified.passworddetectOnlyrevertdetectOnly.windowsDrivebootTimeoutSecondsUse a repair VM created with
az vm repair create --enable-nested, then invoke withaz vm repair run --run-on-repair --run-id win-add-temp-user.Validation
The remediation was exercised using the real product workflow against deliberately broken
disposable VMs, not just static checks. Windows Server 2016 and 2025 were randomly selected
from the available 2016/2019/2025 choices; both selected images are Gen1.
create --enable-nestedand pinnedrun --previewdetectionrestoreto the original VMPreview candidate:
804cd4ae80110bc919e62d9966aadf674d6691b8.Script SHA256:
19789E8023484613D1B337EC31AA491E96C8EE507A259E40A030195C435DC30B.Server 2016 required a forced nested power-off after graceful shutdown timed out. The
script re-read the result and SAM and verified Setup restoration rather than trusting
an unflushed guest state; original-VM verification is recorded separately above.
Server 2025 shut down cleanly. These runs do not establish fresh password/RDP authentication,
Gen2, BitLocker or domain-joined coverage.
The final 2016 guest checks were collected after an additional Azure VM restart and correcting
the verifier's transport. No further scenario changes were made. On both original guests,
the new account was enabled and belonged to Administrators/Remote Desktop Users, the original
fixture account remained disabled, and Setup values and all three temporary artifacts were clear.
The September 2 sign-in test and September 10 helper lifecycle tests remain historical
evidence for their then-current code, not additional fresh coverage for this revision.
Review disposition and scope
The maintainer-supplied agent's report on
b2814df9f55c0e915423c260e1cd43949f69dea7identified 3 Critical, 7 Warning and 4 Info items. Confirmed defects were implemented and
exercised; descriptive findings were clarified. The empty SAM Names-key distinction was
not changed: a normal SAM contains built-in accounts, and the conservative unreadable
classification cannot satisfy the new success gate by itself.
First wave of four independent scenario PRs. Helpers from #143, #146 and #147 are already
merged. This PR changes only the new scenario and its catalog entry, not shared helpers or
other scenarios. Private break/verify/regression tooling is not included in the contribution.