agent docs updates

This commit is contained in:
Oliver Kieselbach
2026-03-31 21:25:51 +02:00
parent db6a2a6254
commit 1a89080f0f
4 changed files with 245 additions and 11 deletions
@@ -0,0 +1,175 @@
# Autopilot Monitor Bootstrap Guard Test
# Dry-run only: does not exit, does not install, only reports what WOULD happen.
param(
[string]$AgentBinPath = 'C:\ProgramData\AutopilotMonitor\Agent'
)
$ErrorActionPreference = 'SilentlyContinue'
function Write-Step {
param(
[string]$Status,
[string]$Message
)
$prefix = switch ($Status) {
'PASS' { '[PASS]' }
'SKIP' { '[SKIP]' }
'WARN' { '[WARN]' }
'INFO' { '[INFO]' }
default { '[....]' }
}
Write-Host "$prefix $Message"
}
function Get-RegistryValueSafe {
param(
[string]$Path,
[string]$Name
)
try {
return (Get-ItemProperty -Path $Path -Name $Name -ErrorAction Stop).$Name
}
catch {
return $null
}
}
$AgentExePath = Join-Path $AgentBinPath 'AutopilotMonitor.Agent.exe'
$MaxBootstrapWindowHours = 12
$wouldInstall = $true
$reasons = New-Object System.Collections.Generic.List[string]
Write-Host ''
Write-Host '=== Autopilot Monitor Bootstrap Guard Test (Dry Run) ==='
Write-Host ''
# Guard 1: Agent was already deployed on this device (survives self-destruct)
$deployed = Get-RegistryValueSafe -Path 'HKLM:\SOFTWARE\AutopilotMonitor' -Name 'Deployed'
if ($deployed) {
Write-Step -Status 'SKIP' -Message "Guard 1: Agent was previously deployed at '$deployed'."
$wouldInstall = $false
$reasons.Add("Previously deployed marker exists: $deployed")
} else {
Write-Step -Status 'PASS' -Message 'Guard 1: No previous deployment marker found.'
}
# Guard 2: Device must be in OOBE (= actively provisioning)
$oobeInProgress = Get-RegistryValueSafe -Path 'HKLM:\SYSTEM\Setup' -Name 'OOBEInProgress'
if ($oobeInProgress -ne 1) {
Write-Step -Status 'SKIP' -Message "Guard 2: Device is not in OOBE (OOBEInProgress=$oobeInProgress). Not a fresh enrollment."
$wouldInstall = $false
$reasons.Add("Not in OOBE (OOBEInProgress=$oobeInProgress)")
} else {
Write-Step -Status 'PASS' -Message 'Guard 2: Device is in OOBE (OOBEInProgress=1).'
}
# Guard 3: No real user profile should exist yet
$excludePattern = '^(defaultuser\d*|Public|Default( User)?|All Users)$'
$wmiProfileQueryFailed = $false
$profileNames = @(
# WMI/CIM view
try {
Get-CimInstance Win32_UserProfile -ErrorAction Stop |
Where-Object {
-not $_.Special -and
$_.LocalPath -like 'C:\Users\*'
} |
ForEach-Object {
Split-Path $_.LocalPath -Leaf
}
}
catch {
$wmiProfileQueryFailed = $true
}
# Filesystem view
(Get-ChildItem 'C:\Users' -Directory -ErrorAction SilentlyContinue).Name
) |
Where-Object {
$_ -and $_ -notmatch $excludePattern
} |
Select-Object -Unique
if ($wmiProfileQueryFailed) {
Write-Step -Status 'WARN' -Message 'Guard 3: WMI profile query failed, filesystem check still applied.'
}
if ($profileNames) {
$names = ($profileNames | Select-Object -First 3) -join ', '
Write-Step -Status 'SKIP' -Message "Guard 3: Real user profile(s) found ($names). Device appears productive."
$wouldInstall = $false
$reasons.Add("Real user profile(s) found: $names")
} else {
Write-Step -Status 'PASS' -Message 'Guard 3: No real user profiles found (combined WMI/filesystem view).'
}
# Guard 4: Bootstrap window check
# NOT "how long may enrollment take" — agent handles that internally (6h emergency break).
# This is "how old can the OOBE state be before I no longer trust it for initial install".
# 12h bootstrap window vs 6h agent emergency break = consistent layered approach.
# Sleep/standby does NOT reset uptime — only real boot/restart does.
$lastBoot = $null
$uptimeHours = $null
try {
$lastBoot = (Get-CimInstance Win32_OperatingSystem -ErrorAction Stop).LastBootUpTime
$uptimeHours = ((Get-Date) - $lastBoot).TotalHours
if ($uptimeHours -gt $MaxBootstrapWindowHours) {
Write-Step -Status 'SKIP' -Message "Guard 4: Device uptime is $([int]$uptimeHours)h. OOBE state is older than accepted bootstrap window of ${MaxBootstrapWindowHours}h."
$wouldInstall = $false
$reasons.Add("Uptime exceeds bootstrap window: $([int]$uptimeHours)h > ${MaxBootstrapWindowHours}h")
} else {
Write-Step -Status 'PASS' -Message "Guard 4: Device uptime is $([int]$uptimeHours)h and within bootstrap window of ${MaxBootstrapWindowHours}h."
}
}
catch {
Write-Step -Status 'WARN' -Message 'Guard 4: Could not determine LastBootUpTime / uptime.'
}
# Guard 5 (existing): Agent binary already present
if (Test-Path $AgentExePath) {
Write-Step -Status 'SKIP' -Message "Guard 5: Agent already installed at '$AgentExePath'."
$wouldInstall = $false
$reasons.Add("Agent binary already present: $AgentExePath")
} else {
Write-Step -Status 'PASS' -Message "Guard 5: Agent binary not present at '$AgentExePath'."
}
Write-Host ''
Write-Host '=== Result ==='
Write-Host ''
if ($wouldInstall) {
Write-Host '[DECISION] WOULD INSTALL agent on this device.'
} else {
Write-Host '[DECISION] WOULD SKIP agent installation on this device.'
}
Write-Host ''
Write-Host '=== Summary ==='
if ($reasons.Count -eq 0) {
Write-Host 'No blocking reasons found.'
} else {
foreach ($reason in $reasons) {
Write-Host " - $reason"
}
}
Write-Host ''
Write-Host '=== Raw Values ==='
Write-Host "Deployed marker : $deployed"
Write-Host "OOBEInProgress : $oobeInProgress"
Write-Host "MaxBootstrapWindowHours : $MaxBootstrapWindowHours"
Write-Host "LastBootUpTime : $lastBoot"
Write-Host "UptimeHours : $([string]$uptimeHours)"
Write-Host "AgentExePath : $AgentExePath"
Write-Host "DetectedProfileNames : $($profileNames -join ', ')"
Write-Host ''