Skip to content

chore(validation): restart the agent the way that works, and bring the kit's scripts and docs up to date - #44

Merged
fadwen merged 1 commit into
mainfrom
docs/validation-kit
Oct 15, 2026
Merged

fadwen merged 1 commit into
mainfrom
docs/validation-kit

Conversation

@fadwen

@fadwen fadwen commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Summary

Six things in the validation kit that a read of its scripts against the latest Findings turned up. None changes an experiment or a result; they are the driver's agent restart, a lab script on the pre-GuestAgent.ps1 transport, help and version headers that describe an earlier version of the kit, and two paths from the monorepo the module came from.

  • Invoke-ValidationRound.ps1 -Action Trigger called Restart-Service IntuneManagementExtension, which round 11 found reports Running and restarts nothing: the stop fails, the process keeps its start time, and the next runner cycle is an hour away. Stopping the service's process and starting the service fetched the new assignments within ten minutes.
  • New-IntuneLabVm.ps1 kept its own synchronous qm guest exec helper, the pattern GuestAgent.ps1 replaced after Windows' process id reuse mixed up the results of uncollected commands.
  • Invoke-LabGuestScript.ps1 said the script parts are written with Set-Content (they go through the agent's file-write call) and that a timed-out status call never runs the script twice (GuestAgent.ps1 reruns a command whose result was lost, up to three times). It and the two probe scripts required PowerShell 7.4 while the driver and the VM script require 7.6.
  • Validation/README.md pointed at Scripts\Entra\Grant-ClaudeDevTenantPermissions.ps1 and cd Scripts\Intune\IntuneScriptLab\Validation, neither of which exists in this repository.
  • Experiments.psd1 opened with "Round 1 experiments"; it holds all 142, from eleven rounds.

Changes

  • Validation/Invoke-ValidationRound.ps1: Trigger stops the service, stops its process if it is still there, starts the service, and prints the status with the process start time before and after, so a restart that did not happen is visible in the output.
  • Validation/New-IntuneLabVm.ps1: dot-sources GuestAgent.ps1; Invoke-Guest is a wrapper that returns $null while the agent is not up, which the OOBE wait polls on.
  • Validation/Invoke-LabGuestScript.ps1, Invoke-AssignmentProbe.ps1, Invoke-FilterProbe.ps1: #Requires -Version 7.6; the first's DESCRIPTION and NOTES describe the file-write transfer and the rerun.
  • Validation/README.md: the permissions line says they are granted as application permissions with admin consent; the workflow starts with cd Validation.
  • Validation/Experiments.psd1: header.
  • CHANGELOG.md: Changed entry under Unreleased.

Verification

  • Validation/Tests/Unit: 62 passed on PowerShell 7.6.6 (the suite lifts the driver's functions through the parser, so the new Trigger body parses).
  • PSScriptAnalyzer (Error, Warning) clean on the three changed scripts; no line over 115 characters under Validation/.
  • Not run: Trigger and New-IntuneLabVm.ps1 against a VM. The lab host was not reachable from the development machine while this PR was prepared. The Trigger body is the sequence round 11 ran by hand (Findings, "Restart-Service ... restarts nothing").

Notes

…e kit's scripts and docs up to date

Trigger called Restart-Service, which reports the service running and
restarts nothing (round 11); it stops the process, starts the service
and prints both start times. New-IntuneLabVm.ps1 makes its guest calls
through GuestAgent.ps1 instead of its own synchronous qm guest exec.
Invoke-LabGuestScript.ps1's help describes the file-write transfer and
the rerun after a lost result; it and the probe scripts require
PowerShell 7.6 like the driver. The README drops two monorepo paths and
the experiment catalog's header says what it holds.

@fadwen fadwen left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes on the lines whose reason the diff does not show.

$before = if ($service.ProcessId) { (Get-Process -Id $service.ProcessId).StartTime.ToString('o') }
Stop-Service -Name $name -Force -ErrorAction SilentlyContinue
if ($service.ProcessId -and (Get-Process -Id $service.ProcessId -ErrorAction SilentlyContinue)) {
Stop-Process -Id $service.ProcessId -Force

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop-Service is tried first and allowed to fail, because on a healthy agent it is the clean path and round 11 only showed it failing on a stuck one. The process id is read before the stop so the kill targets the process that was the service, not whatever Start-Service may have already spawned; the Get-Process check skips the kill when the stop did work.

if ($LASTEXITCODE -ne 0 -or -not $raw) { return $null }
(($raw -join "`n") | ConvertFrom-Json).'out-data'
try { Invoke-GuestPowerShell -Script $Script -TimeoutSeconds 60 -WarningAction SilentlyContinue }
catch { $null }

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept as a wrapper rather than calling Invoke-GuestPowerShell directly: the OOBE wait polls a VM whose agent is not running yet, and GuestAgent.ps1 throws after three failed exec attempts where the old helper returned $null. The wrapper keeps that contract so Wait-GuestAtOobe's loop is unchanged; warnings are silenced for the same reason.

Comment thread Validation/README.md
`DeviceManagementApps.ReadWrite.All`, `DeviceManagementManagedDevices.Read.All`,
`Group.ReadWrite.All`, `Device.Read.All`.
`Scripts\Entra\Grant-ClaudeDevTenantPermissions.ps1` grants them.
`Group.ReadWrite.All`, `Device.Read.All`, granted as application permissions with admin consent.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script this line named lived in the monorepo's Scripts\Entra folder and was not carried over, so the sentence now says what has to be true of the app registration rather than how it was once done.

Base automatically changed from fix/inex-evidence to main October 15, 2026 17:53
@fadwen
fadwen merged commit 55997ac into main Oct 15, 2026
6 of 8 checks passed
@fadwen
fadwen deleted the docs/validation-kit branch October 15, 2026 17:54
@fadwen fadwen mentioned this pull request Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant