mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
bug fix bootstrap
This commit is contained in:
@@ -75,6 +75,7 @@ jobs:
|
||||
run: |
|
||||
dotnet restore src/Agent/AutopilotMonitor.Agent/AutopilotMonitor.Agent.csproj
|
||||
dotnet restore src/Agent/AutopilotMonitor.SummaryDialog/AutopilotMonitor.SummaryDialog.csproj
|
||||
dotnet restore src/Agent/AutopilotMonitor.Agent.Core.Tests/AutopilotMonitor.Agent.Core.Tests.csproj
|
||||
|
||||
- name: Build Agent
|
||||
run: >
|
||||
@@ -90,6 +91,13 @@ jobs:
|
||||
--configuration Release
|
||||
--no-restore
|
||||
|
||||
- name: Run Agent unit tests
|
||||
run: >
|
||||
dotnet test src/Agent/AutopilotMonitor.Agent.Core.Tests/AutopilotMonitor.Agent.Core.Tests.csproj
|
||||
--configuration Release
|
||||
--no-restore
|
||||
--verbosity quiet
|
||||
|
||||
- name: Update buildcounter.txt
|
||||
if: inputs.build_number == ''
|
||||
shell: pwsh
|
||||
|
||||
@@ -111,10 +111,12 @@ try {
|
||||
# -- Pre-flight: Multi-signal guard to prevent installation on non-provisioning devices --
|
||||
# Layered approach: each guard catches a different scenario.
|
||||
# Guard 1: Ghost re-installs (registry marker from previous deployment)
|
||||
# Guard 2: Productive devices (real user profile exists — WMI + filesystem)
|
||||
# Guard 3: Bootstrap window expired (device uptime > 12h without agent)
|
||||
# Guard 4: Agent binary already present from a previous run
|
||||
# NOTE: OOBEInProgress is NOT used — it is unreliable (observed =0 during active enrollment).
|
||||
# Guard 2: Productive devices (real user profile exists -- WMI + filesystem)
|
||||
# Guard 3: Productive devices (a real user has logged on before)
|
||||
# Guard 4: Productive devices (explorer.exe running = user desktop active)
|
||||
# Guard 5: Bootstrap window expired (device uptime > 12h without agent)
|
||||
# Guard 6: Agent binary already present from a previous run
|
||||
# NOTE: OOBEInProgress is NOT used -- it is unreliable (observed =0 during active enrollment).
|
||||
|
||||
# Guard 1: Agent was already deployed on this device (registry marker survives self-destruct)
|
||||
$deployed = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\AutopilotMonitor' -Name 'Deployed' -ErrorAction SilentlyContinue).Deployed
|
||||
@@ -146,7 +148,20 @@ try {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Guard 3: Bootstrap window check (no key, no user profiles, but device running too long)
|
||||
# Guard 3: LastLoggedOnUser -- during Device ESP no real user has logged on yet
|
||||
$lastLoggedOnUser = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI' -Name 'LastLoggedOnUser' -EA SilentlyContinue).LastLoggedOnUser
|
||||
if ($lastLoggedOnUser -and $lastLoggedOnUser -notmatch 'defaultuser\d*') {
|
||||
Write-Log "SKIP: LastLoggedOnUser found ($lastLoggedOnUser). Device appears productive."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Guard 4: explorer.exe running -- during Device ESP no desktop shell is active
|
||||
if (Get-Process explorer -ErrorAction SilentlyContinue) {
|
||||
Write-Log "SKIP: explorer.exe is running. Device appears beyond initial enrollment."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Guard 5: Bootstrap window check (no key, no user profiles, but device running too long)
|
||||
# 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.
|
||||
@@ -159,7 +174,7 @@ try {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Guard 4: Is the agent already installed? (leftover from previous run)
|
||||
# Guard 6: Is the agent already installed? (leftover from previous run)
|
||||
if (Test-Path $AgentBinPath) {
|
||||
$existingAgent = Get-ChildItem -Path $AgentBinPath -Filter "AutopilotMonitor.Agent.exe" -ErrorAction SilentlyContinue
|
||||
if ($existingAgent) {
|
||||
@@ -168,7 +183,7 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
Write-Log "Pre-flight checks passed -- device is in OOBE, no prior deployment, no real user profiles"
|
||||
Write-Log "Pre-flight checks passed -- no prior deployment, no real user profiles, no logged-on user, no explorer"
|
||||
|
||||
# Download and extract agent binaries
|
||||
$agentExePath = Join-Path $AgentBinPath "AutopilotMonitor.Agent.exe"
|
||||
|
||||
@@ -100,7 +100,27 @@ if ($profileNames) {
|
||||
Write-Step -Status 'PASS' -Message 'Guard 2: No real user profiles found (combined WMI/filesystem view).'
|
||||
}
|
||||
|
||||
# Guard 3: Bootstrap window check
|
||||
# Guard 3: LastLoggedOnUser -- during Device ESP no real user has logged on yet
|
||||
$lastLoggedOnUser = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI' -Name 'LastLoggedOnUser' -EA SilentlyContinue).LastLoggedOnUser
|
||||
if ($lastLoggedOnUser -and $lastLoggedOnUser -notmatch 'defaultuser\d*') {
|
||||
Write-Step -Status 'SKIP' -Message "Guard 3: LastLoggedOnUser found ($lastLoggedOnUser). Device appears productive."
|
||||
$wouldInstall = $false
|
||||
$reasons.Add("LastLoggedOnUser found: $lastLoggedOnUser")
|
||||
} else {
|
||||
Write-Step -Status 'PASS' -Message "Guard 3: No real LastLoggedOnUser (value: '$lastLoggedOnUser')."
|
||||
}
|
||||
|
||||
# Guard 4: explorer.exe running -- during Device ESP no desktop shell is active
|
||||
$explorerRunning = $null -ne (Get-Process explorer -ErrorAction SilentlyContinue)
|
||||
if ($explorerRunning) {
|
||||
Write-Step -Status 'SKIP' -Message 'Guard 4: explorer.exe is running. Device appears beyond initial enrollment.'
|
||||
$wouldInstall = $false
|
||||
$reasons.Add('explorer.exe is running')
|
||||
} else {
|
||||
Write-Step -Status 'PASS' -Message 'Guard 4: explorer.exe is not running.'
|
||||
}
|
||||
|
||||
# Guard 5: 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.
|
||||
@@ -113,24 +133,24 @@ try {
|
||||
$uptimeHours = ((Get-Date) - $lastBoot).TotalHours
|
||||
|
||||
if ($uptimeHours -gt $MaxBootstrapWindowHours) {
|
||||
Write-Step -Status 'SKIP' -Message "Guard 3: Device uptime is $([int]$uptimeHours)h. Older than accepted bootstrap window of ${MaxBootstrapWindowHours}h."
|
||||
Write-Step -Status 'SKIP' -Message "Guard 5: Device uptime is $([int]$uptimeHours)h. 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 3: Device uptime is $([int]$uptimeHours)h and within bootstrap window of ${MaxBootstrapWindowHours}h."
|
||||
Write-Step -Status 'PASS' -Message "Guard 5: Device uptime is $([int]$uptimeHours)h and within bootstrap window of ${MaxBootstrapWindowHours}h."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Step -Status 'WARN' -Message 'Guard 3: Could not determine LastBootUpTime / uptime.'
|
||||
Write-Step -Status 'WARN' -Message 'Guard 5: Could not determine LastBootUpTime / uptime.'
|
||||
}
|
||||
|
||||
# Guard 4: Agent binary already present
|
||||
# Guard 6: Agent binary already present
|
||||
if (Test-Path $AgentExePath) {
|
||||
Write-Step -Status 'SKIP' -Message "Guard 4: Agent already installed at '$AgentExePath'."
|
||||
Write-Step -Status 'SKIP' -Message "Guard 6: Agent already installed at '$AgentExePath'."
|
||||
$wouldInstall = $false
|
||||
$reasons.Add("Agent binary already present: $AgentExePath")
|
||||
} else {
|
||||
Write-Step -Status 'PASS' -Message "Guard 4: Agent binary not present at '$AgentExePath'."
|
||||
Write-Step -Status 'PASS' -Message "Guard 6: Agent binary not present at '$AgentExePath'."
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
@@ -157,9 +177,11 @@ if ($reasons.Count -eq 0) {
|
||||
Write-Host ''
|
||||
Write-Host '=== Raw Values ==='
|
||||
Write-Host "Deployed marker : $deployed"
|
||||
Write-Host "DetectedProfileNames : $($profileNames -join ', ')"
|
||||
Write-Host "LastLoggedOnUser : $lastLoggedOnUser"
|
||||
Write-Host "ExplorerRunning : $explorerRunning"
|
||||
Write-Host "MaxBootstrapWindowHours : $MaxBootstrapWindowHours"
|
||||
Write-Host "LastBootUpTime : $lastBoot"
|
||||
Write-Host "UptimeHours : $([string]$uptimeHours)"
|
||||
Write-Host "AgentExePath : $AgentExePath"
|
||||
Write-Host "DetectedProfileNames : $($profileNames -join ', ')"
|
||||
Write-Host ''
|
||||
|
||||
@@ -1 +1 @@
|
||||
738
|
||||
739
|
||||
|
||||
@@ -36,7 +36,19 @@ export function SectionAgentSetup() {
|
||||
<span className="font-mono text-xs bg-green-100 px-1.5 py-0.5 rounded">Win32_UserProfile.Special</span>{" "}
|
||||
) and filesystem checks under{" "}
|
||||
<span className="font-mono text-xs bg-green-100 px-1.5 py-0.5 rounded">C:\Users</span>{" "}
|
||||
— system profiles (defaultuser*, Public, Default) are excluded. Real user profiles indicate the device is already in productive use. This is the primary guard against accidental installation on non-provisioning devices.</span>
|
||||
— system profiles (defaultuser*, Public, Default) are excluded. Real user profiles indicate the device is already in productive use.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold mt-0.5 shrink-0">✓</span>
|
||||
<span><strong>No previous user logon:</strong> Checks{" "}
|
||||
<span className="font-mono text-xs bg-green-100 px-1.5 py-0.5 rounded">LastLoggedOnUser</span>{" "}
|
||||
in the LogonUI registry — during Device ESP no real user has logged on yet. A real username indicates the device has been used interactively.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold mt-0.5 shrink-0">✓</span>
|
||||
<span><strong>No desktop shell:</strong> Checks if{" "}
|
||||
<span className="font-mono text-xs bg-green-100 px-1.5 py-0.5 rounded">explorer.exe</span>{" "}
|
||||
is running — during Device ESP the enrollment status page is shown instead of the Windows desktop. A running explorer process indicates the device is beyond initial enrollment.</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold mt-0.5 shrink-0">✓</span>
|
||||
|
||||
Reference in New Issue
Block a user