mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 04:32:32 +00:00
06cf1c4c12
Two enrollment blind spots become timeline ground truth from the System event log via one EventLogWatcher (WindowsUpdateTracker pattern, 24h backfill with RecordId watermark recovering pre-agent records): - system_clock_changed (Kernel-General 1): oldTime/newTime/signed timeDeltaMs, reason and the setting process. 2s floor suppresses w32time 1ms micro-slews; steps >= 5min are Warning + immediate upload. Payload instants are the authoritative source (event timestamps can be clamped server-side). - system_sleep_episode (Power-Troubleshooter 1 classic sleep/hibernate, Kernel-Power 507 Modern Standby; 506 deliberately unconsumed): kind, enteredAt/exitedAt, durationSeconds, wake source / AC state. 60s real-sleep floor filters Modern Standby screen-off scenarios. ConfigVersion 39 (Collectors.EnableSystemTimelineWatcher + SystemEventBackfillLookbackMinutes). Both types are non-activity on agent and backend (idle/stall clocks unaffected; a sleeping device stays Stalled). Consumers: TimeJumpBadge gains the ground-truth cause "clock-set" (classifyTimeJump matches backward display steps against recorded clock sets); EventTimeline badge blocks for both events plus the previously bare power_state_change; SessionInfoCard keeps the wall-clock duration and adds a standby note; TimeAttributionCalculator builds SleepSpans (RebootSpan clone, AttributionVersion 3) persisted as SleepSeconds/SleepSpansJson and rendered in TimeAttributionLane; ANALYZE-DEV-012 (info, single) fires once per session for episodes >= 5min - deliberately the only new rule, clock findings stay with DEV-008 to avoid duplicate-finding flood. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3554 lines
168 KiB
JSON
Generated
3554 lines
168 KiB
JSON
Generated
{
|
|
"$schema": "../schema/analyze-rule.schema.json",
|
|
"rules": [
|
|
{
|
|
"ruleId": "ANALYZE-APP-001",
|
|
"title": "Win32 App Detection Script Failure",
|
|
"description": "Detects when a Win32 app detection script fails or returns unexpected results.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "detection_failure",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "detectionResult",
|
|
"operator": "equals",
|
|
"value": "NotDetected",
|
|
"required": true,
|
|
"suppressByEvent": {
|
|
"eventType": "app_install_completed",
|
|
"joinField": "appId"
|
|
}
|
|
}
|
|
],
|
|
"explanation": "A Win32 app detection script failed or did not detect the app after installation. This causes the app to appear as 'not installed' despite successful installation. Detection failures that were later resolved by a successful install of the same app are suppressed and do not raise this finding.",
|
|
"remediation": [
|
|
{
|
|
"title": "Fix detection rules",
|
|
"steps": [
|
|
"Review the app's detection rules in Intune",
|
|
"Verify file/registry paths are correct",
|
|
"Test detection script manually on a device"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"detection",
|
|
"win32"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-002",
|
|
"title": "App Installation Error",
|
|
"description": "Detects app installation failures with specific exit codes or HRESULT error codes and suggests fixes.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:app_install_failed"
|
|
],
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "install_error",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "\\b(1601|1602|1603|1618|1619|1620|1622|1624|1625|1633|1638|1653)\\b|0x80070[0-9a-fA-F]+|lpExitCode|unmapped.*exit",
|
|
"required": true,
|
|
"suppressByEvent": {
|
|
"eventType": "app_install_completed",
|
|
"joinField": "appId"
|
|
}
|
|
}
|
|
],
|
|
"explanation": "An app installation failed with a specific error code. Common MSI exit codes: 1603 (Fatal error during installation), 1618 (Another installation already in progress), 1619 (Package could not be opened), 1625 (Installation prohibited by policy). Common HRESULT codes are also captured.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate the error code",
|
|
"steps": [
|
|
"Check the error code in the rule finding details",
|
|
"Look up the specific error code in Microsoft documentation",
|
|
"Review the IME logs on the device: C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\\IntuneManagementExtension.log",
|
|
"Verify all prerequisites for the app are met",
|
|
"Check if another installation was running concurrently (error 1618)"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"msi",
|
|
"error-code"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-003",
|
|
"title": "App Dependency Chain Failure",
|
|
"description": "Detects when an app fails because a dependency app failed to install.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "dependency_failure",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "dependency|prerequisite|required app|depends on|Dependency",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "An app installation failed because one of its dependency apps failed to install. Fix the dependency first, then retry.",
|
|
"remediation": [
|
|
{
|
|
"title": "Fix dependency chain",
|
|
"steps": [
|
|
"Identify which dependency app failed",
|
|
"Fix the dependency app first",
|
|
"Verify dependency chain order in Intune"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"dependency"
|
|
],
|
|
"version": "1.1.0"
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-004",
|
|
"title": "Insufficient Disk Space",
|
|
"description": "Detects when disk space is critically low during enrollment, which can cause app installation failures. Confidence increases when app installations actually failed while disk space was low.",
|
|
"severity": "critical",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:app_install_failed"
|
|
],
|
|
"baseConfidence": 75,
|
|
"conditions": [
|
|
{
|
|
"signal": "low_disk",
|
|
"source": "event_type",
|
|
"eventType": "performance_snapshot",
|
|
"dataField": "disk_free_gb",
|
|
"operator": "lt",
|
|
"value": "5",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "app_failed",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "app_failed",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "Performance monitoring shows disk free space dropped below 5 GB during enrollment. This can cause app installation failures, especially for large Win32 apps.\n\nIf app installations failed in the same session while free space was low, treat storage exhaustion as the likely contributing cause — the confidence score of this finding is raised accordingly. Verify the individual app failures for their concrete error codes before concluding storage was the only cause.",
|
|
"remediation": [
|
|
{
|
|
"title": "Free disk space",
|
|
"steps": [
|
|
"Check device disk size meets minimum requirements",
|
|
"Clean up temporary files and IME cache (C:\\Windows\\IMECache)",
|
|
"Consider using a larger disk image"
|
|
]
|
|
},
|
|
{
|
|
"title": "Reduce disk consumption during enrollment",
|
|
"steps": [
|
|
"Review the total download size of all blocking apps",
|
|
"Stagger large app installations so temporary install files do not accumulate",
|
|
"Use devices with larger drives for app-heavy deployment profiles"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"disk-space",
|
|
"critical"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-005",
|
|
"title": "Content Download Timeout",
|
|
"description": "Detects when app content download times out or fails.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "download_timeout",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "errorPatternId",
|
|
"operator": "regex",
|
|
"value": "IME-DO-TIMEOUT|IME-ERROR-DOWNLOAD|IME-ERROR-NO-CONTENT",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "App content download timed out or failed. This is usually caused by network issues, proxy interference, or CDN problems. The IME log shows a Delivery Optimization timeout or download content error.",
|
|
"remediation": [
|
|
{
|
|
"title": "Improve download speed",
|
|
"steps": [
|
|
"Check network bandwidth",
|
|
"Verify proxy doesn't block *.delivery.mp.microsoft.com",
|
|
"Consider Delivery Optimization configuration"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"download",
|
|
"timeout"
|
|
],
|
|
"version": "1.1.0"
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-006",
|
|
"title": "App Install Retry Loop",
|
|
"description": "Detects when the same app installation is attempted 3 or more times during one enrollment — a retry loop caused by unhonored reboot requests, repeated failures, or detection mismatches.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "install_retry_loop",
|
|
"source": "event_count",
|
|
"eventType": "app_install_started",
|
|
"dataField": "appId",
|
|
"operator": "count_per_group_gte",
|
|
"value": "3",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "The same app was started 3 or more times during this enrollment. Repeated install attempts have several possible causes:\n\n- **Reboot-required loop** — the app requests a reboot (exit code 3010/1641) that the ESP does not honor, so the install-detect-retry cycle repeats\n- **Failure retries** — the install keeps failing and the IME retries it\n- **Detection mismatch** — the install succeeds but the detection rule does not match, so the app is retried as 'not installed'\n\nCheck the app's install results in this session to see which pattern applies; enrollments that legitimately span multiple reboots can also produce additional install starts.",
|
|
"remediation": [
|
|
{
|
|
"title": "Identify the retry cause",
|
|
"steps": [
|
|
"Review this app's install started/completed/failed events in the session timeline",
|
|
"If reboot-related: check the app's return code mapping includes reboot codes (3010, 1641) and verify ESP reboot behavior settings; consider the 'Hard reboot' return code in Intune",
|
|
"If the install keeps failing: look up the failure error code (see the App Installation Error finding if it fired)",
|
|
"If the install succeeds but is retried: fix the app's detection rule (see the Win32 App Detection Script Failure finding)"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"reboot",
|
|
"retry",
|
|
"loop"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-007",
|
|
"title": "Multiple App Installation Failures",
|
|
"description": "Detects when the app tracking summary reports multiple failed app installations.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:app_install_failed"
|
|
],
|
|
"baseConfidence": 75,
|
|
"conditions": [
|
|
{
|
|
"signal": "summary_errors",
|
|
"source": "event_type",
|
|
"eventType": "app_tracking_summary",
|
|
"dataField": "errorCount",
|
|
"operator": "gte",
|
|
"value": "2",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"explanation": "The app tracking summary reports 2 or more failed app installations during enrollment. This suggests a systemic issue rather than an isolated app failure.",
|
|
"remediation": [
|
|
{
|
|
"title": "Review failed apps",
|
|
"steps": [
|
|
"Check the individual app_install_failed events for specific error patterns",
|
|
"Look for a common pattern (all MSI apps, all large apps, all from a specific publisher)",
|
|
"Consider whether a shared prerequisite or dependency is failing"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"summary",
|
|
"multiple-failures"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-008",
|
|
"title": "Slow App Installation",
|
|
"description": "Detects app installations that take longer than 10 minutes.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "slow_app_install",
|
|
"source": "app_install_duration",
|
|
"eventType": "app_install_completed",
|
|
"operator": "gt",
|
|
"value": "600",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "At least one app installation took longer than 10 minutes. This can indicate slow content delivery, installation overhead, or endpoint performance bottlenecks.",
|
|
"remediation": [
|
|
{
|
|
"title": "Analyze slow app behavior",
|
|
"steps": [
|
|
"Identify the affected app from matched evidence in the rule result",
|
|
"Check network throughput and proxy impact during app download",
|
|
"Consider moving large/non-critical apps out of ESP blocking scope"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"performance",
|
|
"slow-install",
|
|
"warning"
|
|
],
|
|
"version": "1.1.0"
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-010",
|
|
"title": "App Reverted to Error After Successful Install",
|
|
"description": "Detects when a specific app (matched by appId) was first reported as successfully installed but subsequently reported an IME enforcement error — while enrollment completed successfully. The app may be broken post-enrollment.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"enabled": true,
|
|
"trigger": "correlation",
|
|
"baseConfidence": 75,
|
|
"conditions": [
|
|
{
|
|
"signal": "app_regression",
|
|
"source": "event_correlation",
|
|
"eventType": "app_install_completed",
|
|
"correlateEventType": "app_install_failed",
|
|
"joinField": "appId",
|
|
"dataField": "errorPatternId",
|
|
"operator": "equals",
|
|
"value": "IME-ERROR-REPORT",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "enrollment_succeeded",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_complete",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 70,
|
|
"explanation": "An app was initially reported as **successfully installed** (`app_install_completed`) but the IME (Intune Management Extension) subsequently reported an **Error** state for the same app via an `IME-ERROR-REPORT` event — while the overall enrollment completed successfully.\n\nThis pattern occurs when the IME re-evaluates enforcement state after the initial install report and detects a failure, e.g. `EnforcementState` transitions from `Success` → `Error`. The affected app and its details are captured in the matched evidence.\n\nCommon causes:\n- A post-install detection check fails (detection rule mismatch)\n- The enforcement error code `-2016345060` (0x87D13B9C) indicates the app state diverged from expected\n- The app may appear installed in the ESP summary but is in an error state on the device\n\n**The enrollment succeeded, but the affected app requires attention.**",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate the app's post-install enforcement state",
|
|
"steps": [
|
|
"Note the appId and appName from the rule finding — these identify the exact affected app",
|
|
"Check the Intune portal: Devices > [Device] > Apps — confirm the current enforcement state of the app",
|
|
"Review IME logs on the device: C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\\IntuneManagementExtension.log",
|
|
"Search the log for the appId and look for 'EnforcementState' transitions (Success → Error) near the enrollment time",
|
|
"Error -2016345060 (0x87D13B9C) typically indicates a detection failure after install — verify the app's detection rule in Intune",
|
|
"Trigger a manual sync (Company Portal or Settings > Accounts > Access work or school > Sync) to force re-evaluation"
|
|
]
|
|
},
|
|
{
|
|
"title": "Fix detection or installation issues",
|
|
"steps": [
|
|
"If detection fails: correct the detection rule (file path, registry key, or PowerShell script) in the Intune app configuration",
|
|
"If the app itself is broken: redeploy or reassign the app to trigger a fresh install",
|
|
"Consider adding a post-install validation script to catch this scenario proactively"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Troubleshoot Win32 app installations",
|
|
"url": "https://learn.microsoft.com/en-us/troubleshoot/mem/intune/app-management/troubleshoot-win32-app-install"
|
|
},
|
|
{
|
|
"title": "Intune Management Extension logs",
|
|
"url": "https://learn.microsoft.com/en-us/mem/intune/apps/intune-management-extension"
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"win32",
|
|
"enforcement",
|
|
"post-install",
|
|
"correlation"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-012",
|
|
"title": "Enforcement Error Resolved by Successful Detection",
|
|
"description": "Detects when an app reported an enforcement error (unmapped exit code) but was subsequently detected as installed. The error is informational — the app installed despite the unmapped exit code.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "correlation",
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "enforcement_error_resolved",
|
|
"source": "event_correlation",
|
|
"eventType": "app_install_failed",
|
|
"correlateEventType": "app_install_completed",
|
|
"joinField": "appId",
|
|
"eventAFilterField": "errorPatternId",
|
|
"eventAFilterOperator": "regex",
|
|
"eventAFilterValue": "IME-ERROR-ENFORCEMENT|IME-ERROR-UNMAPPED-EXIT",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "An app installation initially reported an **enforcement error** (unmapped exit code), but the IME detection check subsequently found the app **is installed**.\n\nThis happens when the MSI/EXE installer returns a non-standard exit code (e.g., 1603) that has no mapping configured in the Intune app definition. The IME treats unmapped exit codes as errors in its enforcement state, but when detection runs afterward, it confirms the app is present on the device.\n\n**The app is installed and functional.** The enforcement error is an Intune app model artifact, not a real installation failure.",
|
|
"remediation": [
|
|
{
|
|
"title": "Configure exit code mapping in Intune",
|
|
"steps": [
|
|
"Open the Intune portal > Apps > [affected app] > Properties > Edit",
|
|
"In the Return codes section, add a mapping for the reported exit code",
|
|
"Map the exit code to 'Success' or 'Soft reboot' depending on the installer behavior",
|
|
"This prevents the enforcement error from appearing in future deployments"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Win32 app return codes in Intune",
|
|
"url": "https://learn.microsoft.com/en-us/mem/intune/apps/apps-win32-app-management#step-4-return-codes"
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"enforcement",
|
|
"exit-code",
|
|
"unmapped",
|
|
"resolved"
|
|
],
|
|
"version": "1.1.0"
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-013",
|
|
"title": "App Detection Failure During ESP (0x87D1041C)",
|
|
"description": "Detects when the Enrollment Status Page failed because Intune could not verify an app was installed (HRESULT 0x87D1041C). The installer ran but the detection rule did not match afterwards.",
|
|
"severity": "critical",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 90,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "esp_failure_settle_started",
|
|
"dataField": "errorCode",
|
|
"operator": "equals",
|
|
"value": "0x87d1041c",
|
|
"description": "Scope this rule to sessions where the ESP terminated against the Apps subcategory with the canonical detection-failure HRESULT. Works for any agent version, since esp_failure_settle_started is emitted by the V2 ProvisioningStatusTracker regardless of how the Installing-app promotion is later classified."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "app_with_detection_failure",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "detectionResult",
|
|
"operator": "equals",
|
|
"value": "NotDetected",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "esp_failure_errorcode",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_settle_started",
|
|
"dataField": "errorCode",
|
|
"operator": "equals",
|
|
"value": "0x87d1041c",
|
|
"required": false
|
|
}
|
|
],
|
|
"explanation": "App **{{appName}}** failed during the Enrollment Status Page with HRESULT **{{errorCode}}** — *Application not detected after installation completed successfully*. The installer reported success but the Intune detection rule (file/registry/script) did not find the app afterwards, so the ESP Apps subcategory failed and the device's enrollment terminated.\n\nThis is a confirmed detection-rule mismatch, NOT an install timeout — the install itself most likely completed (or the installer exited 0). Common root causes:\n\n- The detection rule looks for a registry/file path that the installer doesn't create (wrong path, wrong bitness — e.g. checking HKLM\\SOFTWARE\\... on a 32-bit installer that lands under WOW6432Node).\n- The installer writes the detection artefact AFTER the ESP's detection probe runs (e.g. async post-install task, requires reboot).\n- The detection script returns 0 with no stdout (Intune treats empty stdout as \"not detected\").\n- The installer wrote files to a user profile but the rule looks in System scope (or vice-versa).",
|
|
"remediation": [
|
|
{
|
|
"title": "Validate the detection rule against an installed device",
|
|
"steps": [
|
|
"Open Intune portal → Apps → {{appName}} → Properties → Detection rules",
|
|
"Note the exact path / registry key / script the rule checks",
|
|
"Install the app manually on a reference device (outside Autopilot) and verify the detection artefact actually exists at that path AFTER the installer finishes",
|
|
"For registry rules: check both HKLM\\SOFTWARE\\... and HKLM\\SOFTWARE\\WOW6432Node\\... depending on the installer's bitness",
|
|
"For file rules: ensure the path is what the installer actually writes (case, trailing version folder, ProgramData vs Program Files)",
|
|
"For script detection: test the script in PowerShell as SYSTEM (psexec -s) — it must write at least one line to stdout AND exit 0"
|
|
]
|
|
},
|
|
{
|
|
"title": "Investigate post-install delay",
|
|
"steps": [
|
|
"Check whether the installer schedules an async task (Windows Installer scheduled reboot, service start) that creates the detection artefact only after ESP completes",
|
|
"If yes: either move the detection artefact creation into the synchronous installer path, or add a wait step in the installer wrapper script before exit",
|
|
"As a workaround, change the detection rule to something the synchronous installer writes immediately (typically the MSI ProductCode under HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\)"
|
|
]
|
|
},
|
|
{
|
|
"title": "Cross-check the agent's per-app event",
|
|
"steps": [
|
|
"Look at the app_install_failed event in this session for DataJson.detectionResult — NotDetected confirms Intune's detection probe ran and returned negative",
|
|
"Look at app_install_failed.bytesDownloaded vs bytesTotal — if they match, the package downloaded fully (install error vs. download error)",
|
|
"Cross-reference DataJson.exitCode and hresultFromWin32 — these come from the installer itself and may explain why the detection artefact was not written"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Troubleshoot Windows Autopilot ESP error codes",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/troubleshoot-tsg"
|
|
},
|
|
{
|
|
"title": "Win32 app detection rules in Intune",
|
|
"url": "https://learn.microsoft.com/en-us/mem/intune/apps/apps-win32-add#step-4-detection-rules"
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"detection",
|
|
"esp",
|
|
"0x87d1041c",
|
|
"intune"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-014",
|
|
"title": "MSIX/Store App Failure During ESP (AppX Deployment)",
|
|
"description": "Detects when the Enrollment Status Page failed on the Apps subcategory and the agent's AppX deployment log scan identified a suspected MSIX/Store package. Store/MSIX apps install outside the Win32 pipeline, so the regular per-app tracking sees nothing — this correlation names the likely culprit.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 75,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "verdict",
|
|
"operator": "equals",
|
|
"value": "appx_candidate_identified",
|
|
"description": "Scope this rule to sessions where the settle-window AppX scan found a package whose deployment error matches the ESP failure HRESULT. Weaker verdicts (appx_activity_no_hresult_match, no_appx_candidates) intentionally do not fire this rule — they carry too little signal for an admin-facing finding."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "appx_candidate",
|
|
"source": "event_type",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "topCandidatePackageName",
|
|
"operator": "exists",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "esp_appx_family_errorcode",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_settle_started",
|
|
"dataField": "errorCode",
|
|
"operator": "regex",
|
|
"value": "^0x80073[cd]",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appx_esp_category",
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "espCategory",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appx_esp_errorcode",
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "espErrorCode",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appx_top_candidate_package",
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "topCandidatePackage",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appx_candidate_count",
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "candidateCount",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appx_scan_confidence",
|
|
"source": "event_data",
|
|
"eventType": "esp_appx_failure_analysis",
|
|
"dataField": "confidence",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"explanation": "The ESP **{{espCategory}}/Apps** subcategory failed with HRESULT **{{espErrorCode}}** — an error from the AppX/MSIX deployment stack, i.e. a **Microsoft Store / MSIX app**, not a Win32 app. These apps install via the EnterpriseModernAppManagement CSP and never appear in the IME Win32 sidecar logs, which is why all tracked Win32/WinGet apps in this session can look green while ESP still reports an Apps failure.\n\nThe agent scanned the AppXDeploymentServer event log during the failure settle window and identified **{{topCandidatePackageName}}** (package `{{topCandidatePackage}}`) as the most likely culprit — its deployment error matches the ESP failure code ({{candidateCount}} candidate(s) total, confidence: {{confidence}}).\n\n**This is a correlation-based assessment, not a confirmed root cause** — validate against the AppXDeploymentServer/Operational event log on the device or in the diagnostics archive before acting.",
|
|
"remediation": [
|
|
{
|
|
"title": "Confirm the failing package",
|
|
"steps": [
|
|
"Open Event Viewer → Applications and Services Logs → Microsoft → Windows → AppXDeploymentServer → Operational on the device (or in the diagnostics archive if uploaded)",
|
|
"Filter for Error-level events around the ESP failure time and confirm the package name and HRESULT match this finding",
|
|
"Look up the HRESULT: 0x80073cf9 = generic install failure, 0x80073cf0 = invalid/corrupt package, 0x80073cff = sideloading/licensing policy block, 0x80073d02 = blocked because app is in use"
|
|
]
|
|
},
|
|
{
|
|
"title": "Check Store app assignment and licensing",
|
|
"steps": [
|
|
"Intune portal → Apps → check the assignment of the suspected app: device context vs user context — user-context Store apps installing during Account Setup ESP are a common failure source",
|
|
"Verify the app's license type (online vs offline): online-licensed Store apps require the user's Entra ID token and Store connectivity during ESP",
|
|
"Check whether the Microsoft Store endpoints are reachable from the enrollment network (proxy/firewall allowlists)",
|
|
"If the app is not business-critical during provisioning: remove it from the ESP blocking-app list so a failure no longer terminates enrollment"
|
|
]
|
|
},
|
|
{
|
|
"title": "Consider repackaging",
|
|
"steps": [
|
|
"For maximum ESP reliability, wrap the app as a Win32 (.intunewin) deployment instead of a Store/MSIX assignment — Win32 installs are fully tracked and produce per-app failure telemetry",
|
|
"Alternatively deploy the app post-enrollment (available, not required) so it cannot block the ESP"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Troubleshoot Windows Autopilot ESP error codes",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/troubleshoot-tsg"
|
|
},
|
|
{
|
|
"title": "Add Microsoft Store apps to Intune",
|
|
"url": "https://learn.microsoft.com/en-us/mem/intune/apps/store-apps-microsoft"
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"appx",
|
|
"msix",
|
|
"store",
|
|
"esp",
|
|
"0x80073cf9"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-015",
|
|
"title": "Required App Never Settled — ESP Completion Deferred",
|
|
"description": "The IME reported its user-session completion line, but at least one required app stayed pending — without ever failing or even starting to install — so the agent kept deferring the enrollment completion signal. Typically an assignment/requirement problem (requirement rules never met, dependency never satisfied, or the app needs a context that is not available during ESP, e.g. a VPN client waiting for user sign-in to a portal).",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"version": "1.0.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"trigger": "correlation",
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 55,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "enrollment_complete",
|
|
"operator": "not_exists",
|
|
"description": "Suppress when the pending app eventually settled and the enrollment completed — a transient deferral is normal."
|
|
},
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "not_exists",
|
|
"description": "Suppress when the session failed explicitly — the app/ESP failure rules already cover that path; this rule targets the never-finishing case."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "completion_deferred",
|
|
"source": "event_type",
|
|
"eventType": "agent_trace",
|
|
"dataField": "message",
|
|
"operator": "contains",
|
|
"value": "completion signal deferred",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "apps_pending",
|
|
"source": "event_data",
|
|
"eventType": "app_tracking_summary",
|
|
"dataField": "pending",
|
|
"operator": "gte",
|
|
"value": "1",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "pending_app_names",
|
|
"source": "event_data",
|
|
"eventType": "app_tracking_summary",
|
|
"dataField": "pendingNames",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "pending_app_names",
|
|
"condition": "exists",
|
|
"weight": 5
|
|
}
|
|
],
|
|
"explanation": "The Intune Management Extension wrote its user-session completion line, but the agent observed `{{pending}}` required app(s) still pending (`{{pendingNames}}`) and therefore **deferred the enrollment completion signal** — repeatedly, if this happened across several logons or reboots.\n\nA pending app that never transitions to downloading/installing and never fails is almost always an **assignment or requirement problem**, not an install error:\n\n- requirement rules that are never met on this device (OS/architecture/registry/script checks),\n- an unsatisfied dependency or supersedence chain,\n- an app targeted as *required* for the user ESP that needs something unavailable during provisioning (e.g. a VPN client whose portal sign-in only happens after first logon),\n- user-targeted apps on a device where the user identity never fully registered (see the hybrid user-affinity rule if it also fired).",
|
|
"remediation": [
|
|
{
|
|
"title": "Identify and unblock the pending app",
|
|
"steps": [
|
|
"Check the app names listed in this finding's evidence (pendingNames) — these are the apps the ESP is waiting for.",
|
|
"In Intune, review the app's requirement rules and dependencies; test them on the device (IntuneManagementExtension.log logs each requirement evaluation).",
|
|
"Decide whether the app really must block the ESP: removing it from the ESP's 'blocking apps' list (or making it not-required during enrollment) unblocks completion immediately.",
|
|
"If the app is user-targeted on a hybrid-joined device, verify the user's Entra affinity first — without a signed-in Entra user, user-targeted policy never applies."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Enrollment Status Page — blocking apps",
|
|
"url": "https://learn.microsoft.com/en-us/intune/intune-service/enrollment/windows-enrollment-status"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"apps",
|
|
"esp",
|
|
"completion",
|
|
"assignment",
|
|
"pending"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-APP-016",
|
|
"title": "Required Apps Never Started — ESP Apps Gate Starved",
|
|
"description": "One or more required user-ESP apps never started installing while the ESP AccountSetup apps gate waited on them — the agent observed the ESP page exit with those apps still in a non-terminal, never-started state. Unlike ANALYZE-APP-015 (which reports that completion was DEFERRED because of a pending app, and stays silent once the session reaches a terminal verdict) this rule reports the delivery gap itself and fires regardless of the final outcome: an enrollment that Windows called done while required apps never ran is a successful enrollment with missing software, and the operator must see it.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"version": "1.0.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:session_stalled"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 75,
|
|
"confidenceThreshold": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "starved_apps_present",
|
|
"source": "event_count",
|
|
"eventType": "app_install_starved",
|
|
"operator": "count_gte",
|
|
"value": "1",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "many_starved_apps",
|
|
"source": "event_count",
|
|
"eventType": "app_install_starved",
|
|
"operator": "count_gte",
|
|
"value": "5",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appName",
|
|
"source": "event_type",
|
|
"eventType": "app_install_starved",
|
|
"dataField": "appName",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "state",
|
|
"source": "event_type",
|
|
"eventType": "app_install_starved",
|
|
"dataField": "state",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "many_starved_apps",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
},
|
|
{
|
|
"signal": "appName",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "At least one **required** app assigned to the user ESP never started installing. The Intune Management Extension never moved it out of its initial state (`{{state}}`) — it did not download, did not install, and did not fail — while the ESP AccountSetup apps gate was waiting on it. First app observed: `{{appName}}`.\n\nEvery starved app has its own `app_install_starved` timeline event carrying `appId`, `appName` and `state` — open the timeline and filter on that event type for the complete list.\n\nThis is a **delivery** problem, not an install error, and it is invisible in the Intune console: the app simply never appears. Typical causes:\n\n- far more required apps targeted at the ESP than the gate can service in the available window,\n- requirement rules that are never met on this device (OS / architecture / registry / script checks),\n- an unsatisfied dependency or supersedence chain,\n- an app that needs a context unavailable during provisioning (e.g. a VPN client waiting on a portal sign-in),\n- a mid-ESP reboot that cut the gate short — check whether the mid-ESP reboot advisory also fired for this session.\n\nNote that this finding is independent of the session verdict. A session can be marked **Succeeded** and still be missing every app listed here.",
|
|
"remediation": [
|
|
{
|
|
"title": "Shrink the ESP blocking set",
|
|
"steps": [
|
|
"Open the Enrollment Status Page profile and review the blocking app list — every required app there must finish before the user reaches the desktop.",
|
|
"Move apps that do not have to be present at first logon from *required* to *available*, or remove them from the ESP's blocking apps selection.",
|
|
"Prefer a small, deliberately chosen blocking set (security agent, VPN, management tooling) over the full application catalogue."
|
|
]
|
|
},
|
|
{
|
|
"title": "Unblock the individual apps",
|
|
"steps": [
|
|
"Collect the app names from the `app_install_starved` timeline events in this session.",
|
|
"For each app, review its requirement rules and dependencies in Intune — IntuneManagementExtension.log records every requirement evaluation.",
|
|
"Verify the assignment actually targets the signed-in user (user-targeted apps need an established Entra user affinity; check the hybrid user-affinity finding if it also fired).",
|
|
"Re-run an enrollment and confirm the apps now reach a terminal state before the ESP exits."
|
|
]
|
|
},
|
|
{
|
|
"title": "Rule out a truncated gate",
|
|
"steps": [
|
|
"Check whether a mid-ESP reboot was observed for this session — a forced restart during AccountSetup cuts the apps gate short and can starve everything still queued.",
|
|
"If so, reassign the reboot-forcing device policies to user groups so the restart lands after AccountSetup."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Enrollment Status Page — blocking apps",
|
|
"url": "https://learn.microsoft.com/en-us/intune/intune-service/enrollment/windows-enrollment-status"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Win32 app requirement rules",
|
|
"url": "https://learn.microsoft.com/en-us/intune/intune-service/apps/apps-win32-add"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"apps",
|
|
"esp",
|
|
"starvation",
|
|
"assignment",
|
|
"blocking",
|
|
"delivery-gap"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-CORR-003",
|
|
"title": "Proxy Configuration Causing Download Failure",
|
|
"description": "Correlates an active proxy configuration with app content download failures (Delivery Optimization timeout or download error), suggesting the proxy is blocking or throttling Intune content delivery.",
|
|
"severity": "high",
|
|
"category": "apps",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:app_install_failed"
|
|
],
|
|
"trigger": "correlation",
|
|
"baseConfidence": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "proxy_active",
|
|
"source": "event_type",
|
|
"eventType": "proxy_configuration",
|
|
"dataField": "proxyType",
|
|
"operator": "regex",
|
|
"value": "Proxy|PAC",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "download_failure",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "errorPatternId",
|
|
"operator": "regex",
|
|
"value": "IME-DO-TIMEOUT|IME-ERROR-DOWNLOAD|IME-ERROR-NO-CONTENT",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "app_install_failed",
|
|
"condition": "count >= 2",
|
|
"weight": 15
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"condition": "count >= 1",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"confidenceThreshold": 50,
|
|
"explanation": "A proxy (explicit or PAC-based) is configured on this device and app content downloads failed (Delivery Optimization timeout or download content error). Proxies can block or throttle downloads from *.delivery.mp.microsoft.com and other Intune CDN endpoints.\n\nThis is a common root cause when app downloads fail consistently on proxy-connected corporate networks. Note this rule only fires when the failure is download-related — generic app install errors behind a proxy do not trigger it.",
|
|
"remediation": [
|
|
{
|
|
"title": "Verify proxy bypass for Intune endpoints",
|
|
"steps": [
|
|
"Add *.delivery.mp.microsoft.com to proxy bypass list",
|
|
"Add *.do.dsp.mp.microsoft.com (Delivery Optimization) to bypass list",
|
|
"Add login.microsoftonline.com and *.manage.microsoft.com to bypass list",
|
|
"Verify the PAC file is reachable at enrollment time (before user login)"
|
|
]
|
|
},
|
|
{
|
|
"title": "Check proxy authentication",
|
|
"steps": [
|
|
"Ensure the proxy does not require user authentication during OOBE/device phase",
|
|
"Consider using machine certificate-based proxy authentication",
|
|
"Test with proxy temporarily bypassed to confirm it is the root cause"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"correlation",
|
|
"apps",
|
|
"proxy",
|
|
"network",
|
|
"download",
|
|
"root-cause"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-001",
|
|
"title": "Windows Hello Provisioning Timeout",
|
|
"description": "Detects when Windows Hello for Business provisioning did not start within the expected timeframe after ESP completion.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"baseConfidence": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "hello_timeout",
|
|
"source": "event_type",
|
|
"eventType": "hello_wait_timeout",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "Windows Hello for Business provisioning did not start within the expected time after ESP exit. This may indicate that the Hello policy is not configured, the device doesn't meet prerequisites, or there's a connectivity issue with the Key Registration Service.",
|
|
"remediation": [
|
|
{
|
|
"title": "Verify Windows Hello configuration",
|
|
"steps": [
|
|
"Check if Windows Hello for Business is configured in the tenant",
|
|
"Verify the policy targets the device/user correctly",
|
|
"Ensure the device has a TPM 2.0 (required for WHfB)",
|
|
"Check connectivity to the Key Registration Service (enterpriseregistration.windows.net)"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"device",
|
|
"hello",
|
|
"timeout"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-002",
|
|
"title": "Sustained High Memory Usage During Enrollment",
|
|
"description": "Detects when memory usage stays above 90% across at least 3 performance snapshots during enrollment, indicating sustained memory pressure that can cause app installation failures or system instability.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "2.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 55,
|
|
"conditions": [
|
|
{
|
|
"signal": "sustained_high_memory",
|
|
"source": "event_count",
|
|
"eventType": "performance_snapshot",
|
|
"operator": "count_gte",
|
|
"value": "3",
|
|
"filterField": "memory_used_percent",
|
|
"filterOperator": "gt",
|
|
"filterValue": "90",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "app_failed",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "app_failed",
|
|
"condition": "exists",
|
|
"weight": 20
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"explanation": "Memory usage exceeded 90% in at least 3 performance snapshots during this enrollment — sustained pressure, not a single transient spike. Persistent high memory usage can cause app installation failures, system slowdowns, and ESP timeouts, especially on devices with 8 GB RAM installing several apps concurrently.",
|
|
"remediation": [
|
|
{
|
|
"title": "Reduce memory pressure",
|
|
"steps": [
|
|
"Review which apps are being installed concurrently during ESP",
|
|
"Consider staggering resource-heavy installations",
|
|
"Check minimum RAM requirements for the device (8 GB recommended)",
|
|
"Investigate if background services are consuming excessive memory"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"device",
|
|
"memory",
|
|
"performance"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-003",
|
|
"title": "Unsupported Windows Version",
|
|
"description": "Detects devices enrolling with an OS build that has reached end of support: Windows 11 22H2 (build 22621) or older, which includes every Windows 10 build. Maintenance note: raise the build cutoff to 22631 after Windows 11 23H2 reaches end of support on 2026-11-10.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "2.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 90,
|
|
"conditions": [
|
|
{
|
|
"signal": "old_build",
|
|
"source": "event_data",
|
|
"eventType": "os_info",
|
|
"dataField": "currentBuild",
|
|
"operator": "lte",
|
|
"value": "22621",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "os_version",
|
|
"source": "event_type",
|
|
"eventType": "os_info",
|
|
"dataField": "osVersion",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "This device is running an OS build that has reached end of support:\n\n- **OS:** `{{osVersion}}`\n- **Build:** `{{currentBuild}}`\n\nBuilds up to 22621 cover Windows 11 22H2 and older as well as every Windows 10 release — Microsoft no longer provides security updates or bug fixes for these versions (exception: LTSC/IoT LTSC editions follow their own lifecycle; verify the edition if this device is LTSC). Devices running unsupported OS versions are exposed to known vulnerabilities and may fail compliance checks.",
|
|
"remediation": [
|
|
{
|
|
"title": "Update to a supported Windows 11 version",
|
|
"steps": [
|
|
"Verify the device meets hardware requirements for Windows 11 23H2 or 24H2",
|
|
"Update the Windows Autopilot deployment profile to use a supported OS image (23H2 or later)",
|
|
"If using a custom OS image, rebuild it with a supported Windows 11 version",
|
|
"For existing devices, deploy a Windows 11 feature update via Intune or Windows Update for Business"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Windows 11 release information",
|
|
"url": "https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information"
|
|
},
|
|
{
|
|
"title": "Windows lifecycle (Home and Pro)",
|
|
"url": "https://learn.microsoft.com/en-us/lifecycle/products/windows-11-home-and-pro"
|
|
}
|
|
],
|
|
"tags": [
|
|
"device",
|
|
"os-version",
|
|
"end-of-support",
|
|
"windows-11",
|
|
"windows-10"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-004",
|
|
"title": "Windows Update Failed During Enrollment",
|
|
"description": "Detects a Windows quality/cumulative update that FAILED to install during the OOBE / ESP enrollment window (WindowsUpdateClient EventID 20). A cumulative update failing mid-OOBE is a known cause of enrollment errors and is otherwise invisible in the Intune console.",
|
|
"severity": "high",
|
|
"category": "device",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:windows_update_failed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 70,
|
|
"confidenceThreshold": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "wu_install_failed",
|
|
"source": "event_type",
|
|
"eventType": "windows_update_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "wu_update_title",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_failed",
|
|
"dataField": "updateTitle",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "wu_hresult",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_failed",
|
|
"dataField": "hresult",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "wu_hresult_symbol",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_failed",
|
|
"dataField": "hresultSymbol",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "reboot_pending",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_reboot_pending",
|
|
"dataField": "exists",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"condition": "exists",
|
|
"weight": 20
|
|
},
|
|
{
|
|
"signal": "reboot_pending",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "A Windows Update failed to install during enrollment: **{{updateTitle}}** (error {{hresult}} {{hresultSymbol}}). Windows can install quality/cumulative updates during OOBE (the \"Getting updates\" screen and the ESP \"Install Windows quality updates during OOBE\" option). When one of these fails mid-enrollment it can leave the device in an inconsistent state, force an unexpected reboot, or block the Enrollment Status Page — a failure mode that is otherwise only discoverable by deep manual digging on the device.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate the failed update",
|
|
"steps": [
|
|
"Decode the HRESULT ({{hresult}}) against the Windows Update error reference to identify the failure class (WU agent, CBS/servicing, or network).",
|
|
"Check whether the same KB fails on other devices — a broadly failing cumulative update points at a servicing-stack or content issue rather than a single device.",
|
|
"Consider whether Windows Update during OOBE should be deferred (Autopilot ESP setting / update ring) until the problematic update is superseded.",
|
|
"Confirm the device reached the desktop despite the failure; a failed OOBE update does not always fail the enrollment but frequently correlates with ESP delays."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Windows Update error reference",
|
|
"url": "https://learn.microsoft.com/windows/deployment/update/windows-update-error-reference"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"windows-update",
|
|
"oobe",
|
|
"servicing"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-005",
|
|
"title": "Windows Update Installed During Enrollment",
|
|
"description": "Informational: a Windows quality/cumulative update installed during the OOBE / ESP enrollment window (WindowsUpdateClient EventID 19). Surfaces updates applied mid-enrollment — useful context when correlating enrollment duration, reboots, or later issues with a specific KB.",
|
|
"severity": "info",
|
|
"category": "device",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 50,
|
|
"conditions": [
|
|
{
|
|
"signal": "wu_installed",
|
|
"source": "event_type",
|
|
"eventType": "windows_update_succeeded",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "wu_update_title",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_succeeded",
|
|
"dataField": "updateTitle",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "reboot_pending",
|
|
"source": "event_data",
|
|
"eventType": "windows_update_reboot_pending",
|
|
"dataField": "exists",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "reboot_pending",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"explanation": "One or more Windows updates installed during enrollment (e.g. **{{updateTitle}}**). This is normal when Windows Update runs during OOBE, but it extends enrollment time and can trigger a reboot mid-ESP. Track it when correlating enrollment duration or reboot count with a specific cumulative update, or when a device behaves differently after a particular KB landed during provisioning.",
|
|
"remediation": [
|
|
{
|
|
"title": "Optional review",
|
|
"steps": [
|
|
"No action required for a successful install — this is informational.",
|
|
"If enrollment time or reboot count is a concern, review whether quality updates during OOBE are desired for your Autopilot profile.",
|
|
"Correlate the installed KB with any post-enrollment issues if the device behaves unexpectedly."
|
|
]
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"windows-update",
|
|
"oobe"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-006",
|
|
"title": "OS Build Changed During Enrollment",
|
|
"description": "Informational: the OS build (CurrentBuild.UBR) changed across a reboot during enrollment — an update was installed, regardless of which servicing path delivered it. Deterministic corroboration that works even when the Windows Update event channel shows nothing (registry comparison across restart cannot be lost to timing or logging-path differences).",
|
|
"severity": "info",
|
|
"category": "device",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 70,
|
|
"confidenceThreshold": 50,
|
|
"conditions": [
|
|
{
|
|
"signal": "build_changed",
|
|
"source": "event_type",
|
|
"eventType": "os_build_changed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "previous_build",
|
|
"source": "event_data",
|
|
"eventType": "os_build_changed",
|
|
"dataField": "previousBuild",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "current_build",
|
|
"source": "event_data",
|
|
"eventType": "os_build_changed",
|
|
"dataField": "currentBuild",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "wu_channel_blind",
|
|
"source": "event_type",
|
|
"eventType": "windows_update_channel_census",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "wu_channel_blind",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "The OS build changed from **{{previousBuild}}** to **{{currentBuild}}** across a reboot during enrollment — a Windows update was installed mid-provisioning. This is normal when quality updates run during OOBE, but it adds a reboot and extends enrollment time. If a windows_update_channel_census event is also present, the update installed via a servicing path the Windows Update watcher does not capture yet — its EventID histogram tells which IDs to enable.",
|
|
"remediation": [
|
|
{
|
|
"title": "Optional review",
|
|
"steps": [
|
|
"No action required — this is informational context for enrollment duration and reboot analysis.",
|
|
"Correlate the build jump with reboots and any behavior change after enrollment.",
|
|
"If quality updates during OOBE are not desired for this Autopilot profile, review the ESP 'Install quality updates during OOBE' setting."
|
|
]
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"windows-update",
|
|
"oobe",
|
|
"reboot"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-007",
|
|
"title": "System Clock Skew — TPM Attestation and ESP Timeout Risk",
|
|
"description": "The device's real-time clock deviates from NTP by more than two minutes. Microsoft documents that a clock off by several minutes causes TPM attestation errors (self-deploying/pre-provisioning) and ESP timeouts. Knowledge source: docs/agent/autopilot-ztd-diagnostics.md.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 55,
|
|
"confidenceThreshold": 50,
|
|
"conditions": [
|
|
{
|
|
"signal": "clock_ahead",
|
|
"source": "event_data",
|
|
"eventType": "ntp_time_check",
|
|
"dataField": "offsetSeconds",
|
|
"operator": "gt",
|
|
"value": "120",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "clock_behind",
|
|
"source": "event_data",
|
|
"eventType": "ntp_time_check",
|
|
"dataField": "offsetSeconds",
|
|
"operator": "lt",
|
|
"value": "-120",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"explanation": "The device's system clock is off by **{{offsetSeconds}} seconds** relative to the NTP reference (time.windows.com). Microsoft documents that Autopilot provisioning can fail with TPM attestation errors or ESP timeouts when the real-time clock is off by several minutes — certificate and token validation are time-sensitive.\n\nThis is especially critical for **self-deploying and pre-provisioning** deployments (TPM attestation) and can also skew all client-side timestamps in this session's timeline.",
|
|
"remediation": [
|
|
{
|
|
"title": "Sync the clock before provisioning",
|
|
"steps": [
|
|
"Boot the device to the start of OOBE and establish a network connection.",
|
|
"Run 'w32tm /resync /force' (Shift+F10 command prompt) to sync with time.windows.com.",
|
|
"Ensure UDP port 123 to time.windows.com is open in the deployment network.",
|
|
"Check the BIOS/RTC battery and firmware clock if the skew recurs on the same hardware."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot known issues — device provisioning can fail (clock skew)",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/known-issues"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot requirements — Networking (NTP)",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/requirements?tabs=networking"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"ntp",
|
|
"clock-skew",
|
|
"tpm",
|
|
"esp",
|
|
"known-issue"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-008",
|
|
"title": "Device Clock Wrong During Enrollment — Jump or Sustained Offset",
|
|
"description": "The device's clock changed by five or more minutes mid-session (clock jump) or ran five or more minutes off server time for the whole session (sustained offset), measured against the server receive frame of every uploaded event. Complements ANALYZE-DEV-007, which is a one-shot NTP check at agent startup and misses devices where NTP was unreachable or the clock changed later. IME-log-derived events are excluded from the measurement.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "1.0.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 50,
|
|
"conditions": [
|
|
{
|
|
"signal": "clock_jump",
|
|
"source": "clock_skew",
|
|
"skewMetric": "clock_jump",
|
|
"operator": "gte",
|
|
"value": "300",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "sustained_offset",
|
|
"source": "clock_skew",
|
|
"skewMetric": "sustained_offset",
|
|
"operator": "gte",
|
|
"value": "300",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"explanation": "This device's {{skewSummary}} (five-minute threshold). A clock that is off by five or more minutes breaks time-sensitive enrollment mechanisms: Kerberos tolerates at most 5 minutes of skew (Hybrid Join), Entra ID token validation allows about 5 minutes on token lifetimes, and freshly issued SCEP/PKCS certificates can be rejected as \"not yet valid\" when the clock is more than ~10 minutes behind the CA.\n\nUnlike ANALYZE-DEV-007 (a one-shot NTP comparison at agent startup), this finding is measured across the whole session against the server's receive time — it also catches devices where the NTP check could not run (UDP 123 blocked) or where the clock changed after startup (time sync correcting a wrong RTC, Windows auto-timezone, manual change).",
|
|
"remediation": [
|
|
{
|
|
"title": "Fix the device clock and time source",
|
|
"steps": [
|
|
"Check the BIOS/RTC clock and the CMOS battery if the wrong time recurs on the same hardware.",
|
|
"At OOBE, run 'w32tm /resync /force' (Shift+F10 command prompt) to sync with time.windows.com.",
|
|
"Ensure UDP port 123 to time.windows.com is open in the deployment network.",
|
|
"Review 'Set time automatically' and 'Set time zone automatically' behavior on the deployment image — automatic timezone changes mid-enrollment show up as clock jumps."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot known issues — device provisioning can fail (clock skew)",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/known-issues"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot requirements — Networking (NTP)",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/requirements?tabs=networking"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"clock-skew",
|
|
"clock-jump",
|
|
"time-sync",
|
|
"kerberos",
|
|
"certificates",
|
|
"known-issue"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-009",
|
|
"title": "Battery Critically Low During Enrollment",
|
|
"description": "Detects that the device's battery dropped to 15% or less while enrolling on battery power (power_state_change threshold event from the agent's live power watcher). A device dying mid-enrollment leaves a half-provisioned state that typically needs a full reset; this rule surfaces the risk while there is still time to plug the device in. Uses a single required condition on the agent-stamped thresholdPercent field (the data field 'transition' on the event is unrelated to this rule's 'trigger' property).",
|
|
"severity": "high",
|
|
"category": "device",
|
|
"version": "1.0.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:power_state_change"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 90,
|
|
"confidenceThreshold": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "battery_threshold_15",
|
|
"source": "event_data",
|
|
"eventType": "power_state_change",
|
|
"dataField": "thresholdPercent",
|
|
"operator": "equals",
|
|
"value": "15",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "The device's battery fell below **{{thresholdPercent}}%** while the enrollment was running on battery power. If the battery drains completely mid-enrollment, the device is left in a half-provisioned state — apps, policies, or the user profile may be incomplete, and in most cases the device has to be reset and re-enrolled. The agent detected the threshold crossing live via a Windows power-status notification; the exact percentage at that moment is recorded on the matched power_state_change event in the session timeline.",
|
|
"remediation": [
|
|
{
|
|
"title": "Secure power for the running enrollment",
|
|
"steps": [
|
|
"Connect the device to AC power immediately — the enrollment continues normally once power is stable.",
|
|
"If the device shut down before completing, check whether the session reached the desktop; if not, reset the device (Autopilot reset or reimage) and re-enroll it plugged in.",
|
|
"For technician/White Glove flows, make AC power part of the bench checklist — pre-provisioning on battery is the most common source of this alert.",
|
|
"If this fires across many devices of one model, review that model's battery health (the hardware_spec event carries design vs. full-charge capacity)."
|
|
]
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"power",
|
|
"battery",
|
|
"environment"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-010",
|
|
"title": "Enrollment Switched From AC to Battery Power",
|
|
"description": "Detects that the device lost AC power and switched to battery while the enrollment was running (power_state_change event with transition ac_to_battery from the agent's live power watcher). Uses a single required condition so the match is pinned to one event instance; the event payload carries the battery percentage at the moment of the switch. The agent debounces power flapping (5s) so a brief unplug/replug does not produce this event.",
|
|
"severity": "warning",
|
|
"category": "device",
|
|
"version": "1.0.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:power_state_change"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 85,
|
|
"confidenceThreshold": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "switched_to_battery",
|
|
"source": "event_data",
|
|
"eventType": "power_state_change",
|
|
"dataField": "transition",
|
|
"operator": "equals",
|
|
"value": "ac_to_battery",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "The device switched from AC to battery power mid-enrollment. Enrollments are power-hungry — app downloads, Windows Update and disk encryption drain a battery quickly, and Windows may also throttle CPU and network on battery, slowing the enrollment down. The battery percentage at the moment of the switch is recorded on the matched power_state_change event in the session timeline; if the device stayed on battery, look there for subsequent threshold events (50/30/15%) — a later battery_to_ac event means power was restored.",
|
|
"remediation": [
|
|
{
|
|
"title": "Restore AC power",
|
|
"steps": [
|
|
"Reconnect the device to AC power; the enrollment continues normally.",
|
|
"Check the session timeline for a subsequent battery_to_ac event (power restored) or threshold_crossed events (battery draining) to judge urgency.",
|
|
"If this alert is frequent in a deployment area, check docking stations/USB-C hubs for loose power delivery — a flapping dock is a common cause.",
|
|
"Make 'plugged in during setup' part of the end-user/technician enrollment instructions."
|
|
]
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"power",
|
|
"battery",
|
|
"environment"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-DEV-012",
|
|
"title": "Device Entered Standby During Enrollment",
|
|
"description": "Detects that the device completed a sleep, hibernate or Modern Standby episode of at least 5 minutes while the enrollment was running (system_sleep_episode event from the agent's system timeline watcher, recorded retroactively at wake from the Windows event log — pre-agent episodes are backfilled). Uses a single required condition on the episode's durationSeconds so the match is pinned to one event instance and the interpolated duration is the matched value. Short Modern Standby screen-off scenarios (under 60 s of real sleep) never emit the event, and this rule adds a 5-minute floor so brief lid-close moments do not fire it.",
|
|
"severity": "info",
|
|
"category": "device",
|
|
"version": "1.0.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:system_sleep_episode"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 90,
|
|
"confidenceThreshold": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "slept_during_enrollment",
|
|
"source": "event_data",
|
|
"eventType": "system_sleep_episode",
|
|
"dataField": "durationSeconds",
|
|
"operator": "gte",
|
|
"value": "300",
|
|
"required": true
|
|
}
|
|
],
|
|
"explanation": "The device was asleep for {{durationSeconds}} seconds during the enrollment window. Nothing progresses while the device sleeps — downloads pause, the IME stops processing and the ESP simply waits — so the wall-clock enrollment duration includes this pause and can look much slower than the enrollment actually was. The matched system_sleep_episode event in the session timeline carries the exact enter/exit times, the episode kind (sleep, hibernate or Modern Standby) and, for Modern Standby, whether the device was on AC power. A long unexplained gap in the timeline right before that event is this pause, not missing telemetry.",
|
|
"remediation": [
|
|
{
|
|
"title": "Keep the device awake during enrollment",
|
|
"steps": [
|
|
"Check the matched system_sleep_episode event in the timeline for the episode bounds and kind — the enrollment duration minus the episode duration is the real active time.",
|
|
"If the device slept on battery, connect AC power during setup; Windows sleeps far more aggressively on battery.",
|
|
"Instruct users/technicians to keep the lid open and the device powered until the enrollment finishes.",
|
|
"For recurring cases, review the power plan applied during OOBE/ESP (e.g. via provisioning or Intune policy) — consider disabling sleep on AC for the enrollment window."
|
|
]
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"device",
|
|
"power",
|
|
"standby",
|
|
"sleep",
|
|
"environment"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ENRL-001",
|
|
"title": "Enrollment Failed",
|
|
"description": "Detects when the Autopilot enrollment has explicitly failed.",
|
|
"severity": "critical",
|
|
"category": "enrollment",
|
|
"version": "1.1.2",
|
|
"enabled": true,
|
|
"baseConfidence": 95,
|
|
"conditions": [
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "enrollment_failed_reason",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"dataField": "reason",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "esp_failure_subcategory",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_settle_started",
|
|
"dataField": "failedSubcategory",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "esp_failure_errorcode",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_settle_started",
|
|
"dataField": "errorCode",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "failed_app",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "appName",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "failed_app",
|
|
"condition": "exists",
|
|
"weight": 5
|
|
}
|
|
],
|
|
"explanation": "The Autopilot enrollment has explicitly failed.\n\n**Key facts extracted from this session's events:**\n\n- **Failure reason:** `{{reason}}`\n- **First failed app:** `{{appName}}`\n- **ESP failed subcategory:** `{{failedSubcategory}}`\n- **ESP HRESULT:** `{{errorCode}}`\n\nWhen an ESP Apps-subcategory failure is paired with HRESULT `0x87D1041C`, the device-side install most likely completed but the Intune detection rule did not match afterwards — see the **App Detection Failure During ESP** rule (ANALYZE-APP-013) in this same analysis for the actionable root cause and remediation steps. Any field still shown as a literal `{{…}}` placeholder was simply not recorded for this session — for example, a non-ESP failure path has no ESP failed-subcategory or HRESULT.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate enrollment failure",
|
|
"steps": [
|
|
"Start with the more specific ANALYZE-APP-* / ANALYZE-ESP-* rules that fired alongside this one — they correlate specific HRESULTs to actionable causes (e.g. 0x87D1041C → detection rule mismatch in ANALYZE-APP-013)",
|
|
"Read the `reason` field on the enrollment_failed event for the immediate trigger (e.g. esp_terminal_failure, hello_timeout, max_lifetime)",
|
|
"If a HRESULT is present, look it up against the ESP error catalog (Microsoft Learn: Autopilot ESP error codes)",
|
|
"Review other analyze rule results for correlated issues (disk space, network, app failures)",
|
|
"Check the device event timeline for the sequence of events leading to failure",
|
|
"Verify the Autopilot profile and ESP configuration in Intune"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"enrollment",
|
|
"failed",
|
|
"critical"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ENRL-002",
|
|
"title": "Session Timed Out",
|
|
"description": "Detects when the enrollment session was force-failed by the server-side inactivity timeout (no agent telemetry for the configured SessionTimeoutHours window) without ever completing or explicitly failing.",
|
|
"severity": "high",
|
|
"category": "enrollment",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"baseConfidence": 80,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "enrollment_complete",
|
|
"operator": "not_exists",
|
|
"description": "Suppress when the agent later reported a successful completion. The 5h server timeout can fire before the agent's own 6h max-lifetime, so a slow-but-successful session may complete after the sweep marked it timed out."
|
|
},
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "not_exists",
|
|
"description": "Suppress when an explicit enrollment_failed exists — that path is already covered by ANALYZE-ENRL-001; avoid double-reporting the same session."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "session_timeout",
|
|
"source": "event_type",
|
|
"eventType": "session_timeout",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "timeoutHours",
|
|
"source": "event_data",
|
|
"eventType": "session_timeout",
|
|
"dataField": "timeoutHours",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "desktop_was_reached",
|
|
"source": "event_type",
|
|
"eventType": "desktop_arrived",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "all_tracked_apps_completed",
|
|
"source": "event_data",
|
|
"eventType": "app_tracking_summary",
|
|
"dataField": "isAllCompleted",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": false
|
|
}
|
|
],
|
|
"explanation": "The enrollment session was force-failed by the server-side maintenance sweep after `{{timeoutHours}}` hour(s) of agent inactivity — the device stopped sending telemetry and never reported completion or an explicit failure.\n\nThis usually means the agent process died or the device went offline mid-enrollment (power off, network loss, bluescreen, reimage) rather than a clean enrollment failure. Because there is no terminal `enrollment_failed` event, the more specific app/ESP rules cannot pinpoint a cause — the evidence simply stops at the last event before the gap.\n\n**If the evidence shows the user desktop was reached and all tracked apps completed**, the device most likely got all its content but the ESP never signaled completion — on hybrid-joined devices the usual culprit is the user session never establishing Entra affinity (Account Setup re-running on every logon). Check whether the hybrid user-affinity finding also fired for this session.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate the silent session",
|
|
"steps": [
|
|
"Open the device event timeline and look at the LAST events before the gap — the final phase / app reached is where the device went silent",
|
|
"Check whether the device is still enrolled and online in Intune; a reimaged or powered-off device explains the silence",
|
|
"Look for previous_crash_detected / agent_shutting_down events earlier in the session that hint at an agent or OS crash",
|
|
"If the device is reachable, collect the agent + IME logs and re-run enrollment, correlating with the timeout timestamp",
|
|
"If many sessions time out in the same window, check for a tenant-wide network/connectivity issue or an Intune service incident"
|
|
]
|
|
},
|
|
{
|
|
"title": "Desktop reached and apps done, but no completion",
|
|
"steps": [
|
|
"Sign in as the affected user and run dsregcmd /status — 'SSO State: AzureAdPrt' must be YES; NO means the user never registered with Entra and the Account Setup ESP will loop",
|
|
"Verify Entra Connect syncs both the computer object (userCertificate) and the signing-in user, and that the user's UPN suffix is a verified Entra domain"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"enrollment",
|
|
"timeout",
|
|
"stalled"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ENRL-003",
|
|
"title": "TPM Attestation Failure — Known Error Code",
|
|
"description": "A TPM-attestation-related error code documented in the Microsoft Autopilot known-issues list was observed (0x800705B4, 0x801C03EA, 0x81039001, 0x81039023, 0x81039024, 0x80070490). These block self-deploying and pre-provisioning deployments during 'Securing your hardware'. Observability: attestation precedes MDM enrollment, so in the normal deployment model (agent installed via IME after enrollment) these codes are rarely visible — the rule primarily serves bootstrap-token deployments. See docs/agent/autopilot-ztd-diagnostics.md (Observability section).",
|
|
"severity": "high",
|
|
"category": "enrollment",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:modern_deployment_error"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 55,
|
|
"conditions": [
|
|
{
|
|
"signal": "tpm_hresult_esp_failure",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure",
|
|
"dataField": "errorCode",
|
|
"operator": "regex",
|
|
"value": "(0x)?(800705B4|801C03EA|81039001|81039023|81039024|80070490)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "tpm_hresult_esp_advisory",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure_advisory",
|
|
"dataField": "errorCode",
|
|
"operator": "regex",
|
|
"value": "(0x)?(800705B4|801C03EA|81039001|81039023|81039024|80070490)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "tpm_hresult_modern_deployment",
|
|
"source": "event_type",
|
|
"eventType": "modern_deployment_error",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "(0x)?(800705B4|801C03EA|81039001|81039023|81039024|80070490)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "tpm_hresult_error_detected",
|
|
"source": "event_type",
|
|
"eventType": "error_detected",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "(0x)?(800705B4|801C03EA|81039001|81039023|81039024|80070490)",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"explanation": "A TPM attestation error code from Microsoft's Autopilot known-issues list was observed. These codes block self-deploying mode and pre-provisioning during the **Securing your hardware** step.\n\nCode meanings:\n\n- **0x800705B4** — timeout; the most common cause in self-deploying mode is hardware that is not TPM 2.0 capable (e.g. a virtual machine). Self-deploying mode cannot be used on such devices.\n- **0x801C03EA** — TPM attestation failed, so the Microsoft Entra join with a device token failed.\n- **0x81039001** — E_AUTOPILOT_CLIENT_TPM_MAX_ATTESTATION_RETRY_EXCEEDED; intermittent — a retry of the deployment often succeeds.\n- **0x81039023** — Windows 11 attestation failure; fixed by cumulative update KB5013943 (21H2) or later.\n- **0x81039024** — the TPM firmware has known vulnerabilities; attestation is refused until the firmware is updated.\n- **0x80070490** — AMD platforms with ASP firmware TPM; fixed in later AMD firmware releases.\n\nTPM attestation additionally requires access to `*.microsoftaik.azure.net` and, for firmware TPMs, the vendor EK-certificate endpoints. A real-time clock that is off by several minutes also causes attestation failures (see the session's ntp_time_check event).",
|
|
"remediation": [
|
|
{
|
|
"title": "Match the code to its documented fix",
|
|
"steps": [
|
|
"0x800705B4: verify the device has TPM 2.0 (self-deploying/pre-provisioning is unsupported on VMs).",
|
|
"0x81039001: retry the deployment — this code is documented as intermittent.",
|
|
"0x81039023: install KB5013943 (Windows 11 21H2) or a later cumulative update into the image.",
|
|
"0x81039024 / 0x80070490: update the TPM/system firmware from the OEM.",
|
|
"Verify network access to *.microsoftaik.azure.net and the TPM vendor EK-certificate URL (Intel/Qualcomm/AMD).",
|
|
"Check the session's ntp_time_check event — a clock offset of minutes breaks attestation (w32tm /resync /force)."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot known issues",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/known-issues"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot requirements — Networking (TPM attestation endpoints)",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/requirements?tabs=networking"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"enrollment",
|
|
"tpm",
|
|
"attestation",
|
|
"self-deploying",
|
|
"pre-provisioning",
|
|
"known-issue"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ENRL-004",
|
|
"title": "MDM Enrollment Blocked — Known Error Code",
|
|
"description": "An enrollment-blocking error code documented in the Microsoft Autopilot known-issues/troubleshooting pages was observed (0x80180014, 0x80180018, 0xC1036501, 0x801C03F3, 0x80070774). Each has a specific, documented cause and fix. Observability: a blocked MDM enrollment normally means no agent gets installed at all (IME install happens after enrollment) — this rule can realistically only fire for bootstrap-token deployments (pre-MDM reporting) or mixed retry scenarios. See docs/agent/autopilot-ztd-diagnostics.md (Observability section).",
|
|
"severity": "high",
|
|
"category": "enrollment",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 55,
|
|
"conditions": [
|
|
{
|
|
"signal": "enrl_hresult_esp_failure",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure",
|
|
"dataField": "errorCode",
|
|
"operator": "regex",
|
|
"value": "(0x)?(80180014|80180018|C1036501|801C03F3|80070774)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrl_hresult_esp_advisory",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure_advisory",
|
|
"dataField": "errorCode",
|
|
"operator": "regex",
|
|
"value": "(0x)?(80180014|80180018|C1036501|801C03F3|80070774)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrl_hresult_modern_deployment",
|
|
"source": "event_type",
|
|
"eventType": "modern_deployment_error",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "(0x)?(80180014|80180018|C1036501|801C03F3|80070774)",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "enrl_hresult_error_detected",
|
|
"source": "event_type",
|
|
"eventType": "error_detected",
|
|
"dataField": "message",
|
|
"operator": "regex",
|
|
"value": "(0x)?(80180014|80180018|C1036501|801C03F3|80070774)",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"explanation": "An enrollment-blocking error code from Microsoft's Autopilot known-issues list was observed.\n\nCode meanings:\n\n- **0x80180014** — either the device is being reused in self-deploying/pre-provisioning mode and its Intune-created device record still exists (documented ETW companion error: \"Enrollment blocked for AP device by SDM One Time Limit Check\"), or Windows (MDM) enrollment is disabled by an enrollment restriction.\n- **0x80180018** — MDM enrollment refused for the user: missing/incorrect Intune, EMS, or Microsoft 365 license, or the user exceeded the device enrollment limit.\n- **0xC1036501** — automatic MDM enrollment is impossible because multiple MDM configurations exist in Microsoft Entra ID.\n- **0x801C03F3** — the Microsoft Entra device object for this Autopilot device was deleted (logged in the Microsoft-Windows-User Device Registration/Admin channel). The object is Autopilot's anchor for group membership and profile targeting.\n- **0x80070774** — hybrid-join ESP failure caused by a domain mismatch: the Intune Connector for Active Directory is installed in a different AD domain than the one the device is targeted at.",
|
|
"remediation": [
|
|
{
|
|
"title": "Match the code to its documented fix",
|
|
"steps": [
|
|
"0x80180014 (reuse): Intune → Devices → Enrollment → Windows Autopilot → Devices → select the device → 'Unblock device', then redeploy. Alternatively verify Windows (MDM) is set to Allow in the enrollment restrictions.",
|
|
"0x80180018: verify the signing-in user has a valid Intune/EMS/M365 license and has not hit the device enrollment limit.",
|
|
"0xC1036501: consolidate to a single MDM configuration in Microsoft Entra ID.",
|
|
"0x801C03F3: deregister the device from Intune, Entra ID, and Autopilot, then re-register it — this recreates the Entra device object.",
|
|
"0x80070774: install/configure the Intune Connector for Active Directory in the AD domain that matches the device targeting."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot troubleshooting FAQ",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/troubleshooting-faq"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot known issues",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/known-issues"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"enrollment",
|
|
"mdm",
|
|
"known-issue",
|
|
"entra-id",
|
|
"hybrid-join"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ENRL-005",
|
|
"title": "Hybrid Join Timeout 0x80004005 — Fixed by Windows Update",
|
|
"description": "A Microsoft Entra hybrid join Autopilot deployment hit error 0x80004005 — a documented build-dependent known issue, resolved by KB5065789 (25H2, build >= 26200.6725), KB5065426 (24H2, build >= 26100.6584), and KB5070312 (23H2, build >= 22631.6276). Knowledge source: docs/agent/autopilot-ztd-diagnostics.md (error-code map).",
|
|
"severity": "high",
|
|
"category": "enrollment",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "correlation",
|
|
"baseConfidence": 25,
|
|
"confidenceThreshold": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "hybrid_join_profile",
|
|
"source": "event_data",
|
|
"eventType": "autopilot_profile",
|
|
"dataField": "isHybridJoin",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "e_fail_esp_failure",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure",
|
|
"dataField": "errorCode",
|
|
"operator": "contains",
|
|
"value": "80004005",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "e_fail_esp_advisory",
|
|
"source": "event_data",
|
|
"eventType": "esp_failure_advisory",
|
|
"dataField": "errorCode",
|
|
"operator": "contains",
|
|
"value": "80004005",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "e_fail_modern_deployment",
|
|
"source": "event_type",
|
|
"eventType": "modern_deployment_error",
|
|
"dataField": "message",
|
|
"operator": "contains",
|
|
"value": "80004005",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "e_fail_error_detected",
|
|
"source": "event_type",
|
|
"eventType": "error_detected",
|
|
"dataField": "message",
|
|
"operator": "contains",
|
|
"value": "80004005",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "e_fail_esp_failure",
|
|
"condition": "exists",
|
|
"weight": 40
|
|
},
|
|
{
|
|
"signal": "e_fail_esp_advisory",
|
|
"condition": "exists",
|
|
"weight": 35
|
|
},
|
|
{
|
|
"signal": "e_fail_modern_deployment",
|
|
"condition": "exists",
|
|
"weight": 40
|
|
},
|
|
{
|
|
"signal": "e_fail_error_detected",
|
|
"condition": "exists",
|
|
"weight": 35
|
|
}
|
|
],
|
|
"explanation": "This is a **Microsoft Entra hybrid join** deployment that hit error **0x80004005** — a documented, build-dependent Autopilot known issue where hybrid deployments time out.\n\nThe issue is fixed by Windows cumulative updates:\n\n- Windows 11 **25H2**: KB5065789 — fixed from build **26200.6725**\n- Windows 11 **24H2**: KB5065426 — fixed from build **26100.6584**\n- Windows 11 **23H2**: KB5070312 — fixed from build **22631.6276**\n\nCompare this session's OS build (see the Session Info card / os_info event) against the fixed-build threshold for its version. If the device booted with an older build, updating the deployment image (or installing quality updates during OOBE) resolves the timeout. Note that 0x80004005 is a generic failure code (E_FAIL) — if the build is already at or above the fixed threshold, investigate the Intune Connector for Active Directory and domain-controller connectivity instead.",
|
|
"remediation": [
|
|
{
|
|
"title": "Update the image to the fixed build",
|
|
"steps": [
|
|
"Determine the session's OS build from the Session Info card (e.g. 26100.4500).",
|
|
"25H2: ensure build >= 26200.6725 (KB5065789). 24H2: ensure build >= 26100.6584 (KB5065426). 23H2: ensure build >= 22631.6276 (KB5070312).",
|
|
"Refresh the deployment image with the current cumulative update, or enable quality updates during OOBE in the ESP profile.",
|
|
"If the build already contains the fix: check Intune Connector for AD health, domain-controller reachability from the client network, and hybrid-join prerequisites."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Windows Autopilot known issues — hybrid join 0x80004005",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/known-issues"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"enrollment",
|
|
"hybrid-join",
|
|
"known-issue",
|
|
"windows-update",
|
|
"esp"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ESP-001",
|
|
"title": "ESP Blocking App Timeout",
|
|
"description": "Detects when the DeviceSetup phase of the ESP took longer than 30 minutes, indicating a stuck or very slow blocking app. Confidence increases when the phase exceeds 60 minutes.",
|
|
"severity": "high",
|
|
"category": "esp",
|
|
"version": "1.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 50,
|
|
"conditions": [
|
|
{
|
|
"signal": "esp_stalled",
|
|
"source": "phase_duration",
|
|
"eventType": "esp_phase_changed",
|
|
"dataField": "espPhase",
|
|
"operator": "equals",
|
|
"value": "DeviceSetup",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "long_esp",
|
|
"condition": "phase_duration > 1800",
|
|
"weight": 40
|
|
},
|
|
{
|
|
"signal": "very_long_esp",
|
|
"condition": "phase_duration > 3600",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"confidenceThreshold": 70,
|
|
"explanation": "The ESP DeviceSetup phase took more than 30 minutes. This indicates a blocking app is stuck installing, downloading very slowly, or has entered a retry loop. A duration beyond 60 minutes raises the confidence further — at that point the enrollment is almost certainly held by a single stuck blocking item rather than ordinary slowness.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate blocking app",
|
|
"steps": [
|
|
"Identify which app is blocking (check ESP events)",
|
|
"Verify app content is downloadable",
|
|
"Consider reducing the number of blocking apps"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"esp",
|
|
"blocking",
|
|
"timeout",
|
|
"duration"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ESP-002",
|
|
"title": "ESP Subcategory Failed (Certificates)",
|
|
"description": "Detects when the Certificates subcategory of the Enrollment Status Page reported a failure, even if the enrollment later appears to have succeeded. Users can click 'Continue anyway' on an ESP error, which masks the underlying certificate provisioning failure — this rule surfaces the transition so it stays visible.",
|
|
"severity": "high",
|
|
"category": "esp",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "certificates_subcategory_failed",
|
|
"source": "event_data",
|
|
"eventType": "esp_provisioning_status",
|
|
"dataField": "failedSubcategories",
|
|
"operator": "contains",
|
|
"value": "Certificates",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceFactors": [],
|
|
"confidenceThreshold": 70,
|
|
"explanation": "The ESP Certificates subcategory transitioned to **failed** during enrollment. This is frequently masked when the user clicks 'Continue anyway' on the ESP error screen — the overall enrollment then appears successful while a required certificate (e.g. Wi-Fi, VPN, SCEP/PKCS) was never deployed.\n\nThe subcategory name is read from the registry (`CertificatesSubcategory`) and is language-invariant, so this rule fires regardless of OS display language.",
|
|
"remediation": [
|
|
{
|
|
"title": "Validate certificate delivery on the device",
|
|
"steps": [
|
|
"Run `certutil -store My` and `certutil -store -user My` on the device to inspect installed certificates",
|
|
"Check `Event Viewer → Applications and Services Logs → Microsoft → Windows → DeviceManagement-Enterprise-Diagnostics-Provider → Admin` for SCEP/PKCS errors",
|
|
"Review the Intune portal for the device's certificate profile assignments and deployment status"
|
|
]
|
|
},
|
|
{
|
|
"title": "Fix common certificate provisioning issues",
|
|
"steps": [
|
|
"Verify the NDES/SCEP connector is online and healthy",
|
|
"Confirm the certificate template permissions grant 'Enroll' to the Intune service account / NDES computer account",
|
|
"Check that the device has network line-of-sight to the SCEP endpoint at the time of ESP",
|
|
"Re-sync the device (Settings → Accounts → Access work or school → Info → Sync) and re-check the Certificates subcategory"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Troubleshoot certificate profiles in Intune",
|
|
"url": "https://learn.microsoft.com/en-us/mem/intune/protect/troubleshoot-certificate-profiles"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Enrollment Status Page tracking",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/enrollment-status"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"esp",
|
|
"certificates",
|
|
"subcategory",
|
|
"silent-failure"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ESP-004",
|
|
"title": "ESP Timeout with 'Continue Anyway' (Soft Failure)",
|
|
"description": "Detects an ESP terminal failure on a profile that allows 'Continue anyway'. The enrollment is reported as failed, but the user most likely dismissed the error screen and reached the desktop — a soft failure rather than an unusable device.",
|
|
"severity": "warning",
|
|
"category": "esp",
|
|
"version": "1.0.1",
|
|
"enabled": true,
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "enrollment_failed",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "may_have_continued",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"dataField": "mayHaveContinuedAnyway",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "espSyncFailureTimeoutMinutes",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"dataField": "espSyncFailureTimeoutMinutes",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "failedSubcategory",
|
|
"source": "event_type",
|
|
"eventType": "enrollment_failed",
|
|
"dataField": "failedSubcategory",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "appName",
|
|
"source": "event_type",
|
|
"eventType": "app_install_failed",
|
|
"dataField": "appName",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "appName",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "This enrollment was reported as **failed** because the Enrollment Status Page reached its configured terminal timeout (`{{espSyncFailureTimeoutMinutes}} min`) before all blocking items finished. The ESP profile, however, allows **'Continue anyway'** — so the user most likely dismissed the error screen and reached the desktop with a working, though not fully provisioned, device.\n\nThe agent only observes the ESP terminal failure on the device side; it cannot see what the user did after the failure screen. Treat this as a **soft failure**: the device may well be in productive use, while at least one blocking item (`{{failedSubcategory}}` subcategory / app `{{appName}}`) did not complete inside the ESP window.\n\nA cluster of these across a tenant almost always points at one slow blocking app holding the whole fleet at the ESP timeout wall, not at broken devices. Any field still shown as a literal `{{…}}` placeholder was simply not recorded for this session (e.g. a certificate-only failure has no failed app).",
|
|
"remediation": [
|
|
{
|
|
"title": "Relieve ESP pressure so enrollments finish inside the window",
|
|
"steps": [
|
|
"Identify the slow blocking app (`{{appName}}`) and either remove it from the ESP 'block device use until these required apps are installed' list, or raise the ESP installation timeout (currently {{espSyncFailureTimeoutMinutes}} min).",
|
|
"If the app legitimately needs longer than the ESP allows, make it non-blocking and let it install after the desktop arrives.",
|
|
"Verify the app's detection rule matches after install — an app that installs but fails detection times out the ESP on every device (see ANALYZE-APP-013).",
|
|
"If a subcategory such as Certificates is reported under '{{failedSubcategory}}', confirm the certificate/connector actually delivers — 'Continue anyway' hides a missing certificate, it does not fix it."
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"esp",
|
|
"timeout",
|
|
"continue-anyway",
|
|
"soft-failure",
|
|
"enrollment"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ESP-005",
|
|
"title": "MDM Policy Forced a Mid-ESP Reboot (Second Sign-In)",
|
|
"description": "Attributes an observed enrollment reboot to device-assigned MDM policies that Windows flagged as reboot-required. Fires ONLY when both facts are present in the session: at least one actually-observed reboot (system_reboot_detected) AND reboot-required policy flags (mdm_policy_reboot_required). Policy flags alone — e.g. from a user-policy sync during AccountSetup — force no reboot and stay advisory-silent.",
|
|
"severity": "warning",
|
|
"category": "esp",
|
|
"version": "1.3.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed",
|
|
"on_event:session_stalled"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 70,
|
|
"conditions": [
|
|
{
|
|
"signal": "reboot_forcing_policy_uri",
|
|
"source": "event_data",
|
|
"eventType": "mdm_policy_reboot_required",
|
|
"dataField": "firstRebootUri",
|
|
"operator": "exists",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "reboot_observed",
|
|
"source": "event_count",
|
|
"eventType": "system_reboot_detected",
|
|
"operator": "count_gte",
|
|
"value": "1",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "multiple_reboot_uris",
|
|
"source": "event_data",
|
|
"eventType": "mdm_policy_reboot_required",
|
|
"dataField": "uriCount",
|
|
"operator": "gte",
|
|
"value": "2",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "omadm_reboot_flag_set",
|
|
"source": "event_data",
|
|
"eventType": "mdm_policy_reboot_required",
|
|
"dataField": "omadmRebootRequiredFlag",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "multiple_reboot_uris",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
},
|
|
{
|
|
"signal": "omadm_reboot_flag_set",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"confidenceThreshold": 70,
|
|
"explanation": "This session **rebooted during enrollment**, and Windows flagged one or more device-assigned MDM policies as **reboot-required** — the classic cause of the coalesced mid-ESP restart and the unexpected **second sign-in screen** before AccountSetup.\n\nFirst reboot-forcing policy URI: `{{firstRebootUri}}`\n\nThe complete URI list is in the `mdm_policy_reboot_required` timeline event (`rebootUris`). Policies applied DURING ESP DeviceSetup are coalesced into one forced restart at the end of DeviceSetup; the same flags raised later (e.g. user-policy sync in AccountSetup) have no immediate effect — this advisory only fires when a reboot was actually observed.\n\nThis is expected OS behavior, not a failure — but it degrades the enrollment experience, confuses users, and is invisible in the Intune console.",
|
|
"remediation": [
|
|
{
|
|
"title": "Reassign the reboot-forcing policies to user groups",
|
|
"steps": [
|
|
"Open the `mdm_policy_reboot_required` timeline event and note the CSP URIs in `rebootUris` (e.g. `./Device/Vendor/MSFT/...`)",
|
|
"Map each URI to its Intune profile (Settings Catalog / configuration profile) — the URI path names the CSP area",
|
|
"Reassign those profiles from device groups to user groups so they apply during/after AccountSetup instead of DeviceSetup",
|
|
"Alternatively, exclude the Autopilot device group from the profile and deliver the setting post-enrollment"
|
|
]
|
|
},
|
|
{
|
|
"title": "Or accept the reboot and set expectations",
|
|
"steps": [
|
|
"If the policy must be device-assigned (e.g. a security baseline), keep it and document the expected mid-ESP restart",
|
|
"Communicate to users that a restart and second sign-in during provisioning is expected for these deployments"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Patch My PC: Avoid the second sign-in screen after Autopilot",
|
|
"url": "https://patchmypc.com/blog/autopilot-unexpected-reboot-autopilot-second-login-screen/"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Enrollment Status Page tracking",
|
|
"url": "https://learn.microsoft.com/en-us/autopilot/enrollment-status"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"esp",
|
|
"reboot",
|
|
"coalescing",
|
|
"second-sign-in",
|
|
"policy-attribution",
|
|
"user-experience"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ESP-006",
|
|
"title": "ESP Failure Recovered After User Retry",
|
|
"description": "Detects the recovery story: the ESP reported a terminal failure (typically DeviceSetup/Apps), the user most likely pressed 'Try again' on the failure page, the failed step re-ran and completed successfully. The earlier failure did not stick — the enrollment continued past it.",
|
|
"severity": "info",
|
|
"category": "esp",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 85,
|
|
"conditions": [
|
|
{
|
|
"signal": "advisory",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_advisory",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "recovered",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_recovered",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "retry",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_retry_detected",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "category",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_recovered",
|
|
"dataField": "category",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "failedSubcategory",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_recovered",
|
|
"dataField": "failedSubcategory",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "likelyCulpritApps",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_advisory",
|
|
"dataField": "likelyCulpritApps",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "minutesSinceFailure",
|
|
"source": "event_type",
|
|
"eventType": "esp_failure_recovered",
|
|
"dataField": "minutesSinceFailure",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "retry",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
},
|
|
{
|
|
"signal": "likelyCulpritApps",
|
|
"condition": "exists",
|
|
"weight": 5
|
|
}
|
|
],
|
|
"explanation": "The Enrollment Status Page reported a **failure** in the `{{category}}` phase (`{{failedSubcategory}}` subcategory, most likely app(s): `{{likelyCulpritApps}}`) — and then **recovered**: the failed step left its failed state and completed successfully about `{{minutesSinceFailure}}` min later.\n\nThat pattern is consistent with the user pressing **'Try again'** on the ESP failure page (the profile allows failure-page actions; the agent cannot observe the click itself). The failure the user saw was real, but it did not stick — the ESP re-ran the step, it succeeded, and the enrollment continued.\n\nRead the session timeline as one arc: `esp_failure_advisory` (the failure, with the likely culprit app) → `esp_failure_retry_detected` (the retry) → `esp_failure_recovered` (the recovery). If this pattern repeats across devices for the same app, that app's install is flaky on first attempt — fix the app rather than the devices. Any literal `{{…}}` placeholder means that detail was not recorded for this session.",
|
|
"remediation": [
|
|
{
|
|
"title": "Make the first install attempt stick",
|
|
"steps": [
|
|
"Check the likely culprit app(s) (`{{likelyCulpritApps}}`) in Intune: an app that fails on the first ESP pass but succeeds on retry usually has a dependency/ordering or detection-timing problem.",
|
|
"If the app shows 'never started installing' in esp_failure_settle_started, verify its assignment and applicability rules — ESP counted it as required, but IME never processed it.",
|
|
"If the pattern repeats across the tenant, consider removing the app from the ESP blocking list until the first-attempt install is reliable — users are seeing an avoidable failure screen.",
|
|
"No device-side action is needed for this session: the failure recovered and the enrollment continued."
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"esp",
|
|
"recovery",
|
|
"try-again",
|
|
"retry",
|
|
"continue-anyway",
|
|
"enrollment"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ID-001",
|
|
"title": "Expected Machine Certificate Not Found",
|
|
"description": "Detects when a certificate with the configured subject is missing from the local machine personal store (LocalMachine\\My). Requires the gather rule GATHER-ID-002 (machine cert store inventory) to be enabled — the check runs against its gather_machine_cert_store output. A missing certificate may indicate that MDM enrollment certificate provisioning or SCEP certificate deployment failed.",
|
|
"severity": "warning",
|
|
"category": "identity",
|
|
"isCommunity": true,
|
|
"enabled": false,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"version": "1.3.0",
|
|
"baseConfidence": 75,
|
|
"conditions": [
|
|
{
|
|
"signal": "cert_store_gathered",
|
|
"source": "event_type",
|
|
"eventType": "gather_machine_cert_store",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "cert_subject_missing",
|
|
"source": "event_data",
|
|
"eventType": "gather_machine_cert_store",
|
|
"dataField": "output",
|
|
"operator": "not_contains",
|
|
"value": "CN=YOUR-CERTIFICATE-SUBJECT",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 70,
|
|
"explanation": "The expected certificate with the configured subject was not found in the local machine certificate store (LocalMachine\\My). Customize the 'value' field in the 'cert_subject_missing' condition to match your expected certificate subject (e.g. 'CN=Contoso Root CA'). The check is case-insensitive (substring match). This rule depends on the gather rule GATHER-ID-002 delivering the machine cert store inventory (gather_machine_cert_store event) — without it the rule never evaluates. If the certificate should have been provisioned via SCEP or MDM enrollment, this may indicate a deployment failure.",
|
|
"remediation": [
|
|
{
|
|
"title": "Verify the expected certificate",
|
|
"steps": [
|
|
"Customize the analyze rule: change 'CN=YOUR-CERTIFICATE-SUBJECT' to your expected certificate subject (case-insensitive substring match)",
|
|
"Example subjects: 'CN=Contoso SCEP Cert', 'CN=Contoso Root CA', 'CN=MDM Device Certificate'",
|
|
"Check certlm.msc (Certificates - Local Computer > Personal > Certificates) manually to see what's present"
|
|
]
|
|
},
|
|
{
|
|
"title": "Troubleshoot missing certificate",
|
|
"steps": [
|
|
"Check if the device is properly enrolled in Intune (dsregcmd /status)",
|
|
"Verify SCEP/PKCS certificate profiles are assigned and targeted correctly",
|
|
"Check the NDES/SCEP connector status and reachability",
|
|
"Review IntuneManagementExtension logs for certificate enrollment errors",
|
|
"Ensure prerequisite certificates (Trusted Root CA) are deployed before the end-entity profile"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"identity",
|
|
"certificates",
|
|
"machine-store",
|
|
"subject-check"
|
|
],
|
|
"templateVariables": [
|
|
{
|
|
"name": "cert_subject",
|
|
"label": "Certificate Subject",
|
|
"description": "The expected certificate subject in your environment (e.g., 'CN=Contoso Root CA'). Case-insensitive substring match against the local machine certificate store.",
|
|
"conditionIndex": 1,
|
|
"field": "value",
|
|
"placeholder": "CN=YOUR-CERTIFICATE-SUBJECT"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ID-002",
|
|
"title": "Unexpected Local Admin Accounts Detected",
|
|
"description": "Detects when the LocalAdminAnalyzer flags unexpected local user accounts or profile directories on the device. This is a known Autopilot bypass technique where admin accounts are created before or during enrollment to gain persistent local admin access.",
|
|
"severity": "high",
|
|
"category": "identity",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 60,
|
|
"conditions": [
|
|
{
|
|
"signal": "unexpected_admins_found",
|
|
"source": "event_type",
|
|
"eventType": "local_admin_analysis",
|
|
"dataField": "finding",
|
|
"operator": "equals",
|
|
"value": "unexpected_local_admins_detected",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "high_confidence",
|
|
"source": "event_data",
|
|
"eventType": "local_admin_analysis",
|
|
"dataField": "confidence_score",
|
|
"operator": "gte",
|
|
"value": "60",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "error_severity",
|
|
"source": "event_data",
|
|
"eventType": "local_admin_analysis",
|
|
"dataField": "severity",
|
|
"operator": "equals",
|
|
"value": "error",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "high_confidence",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
},
|
|
{
|
|
"signal": "error_severity",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"confidenceThreshold": 50,
|
|
"explanation": "The agent detected unexpected local user accounts or profile directories on this device that are not in the built-in or tenant-configured allowed list.\n\nThis is a security-relevant finding. Creating local admin accounts before or during Autopilot enrollment is a known bypass technique (e.g. via BypassNRO or Shift+F10 during OOBE) that grants persistent local administrator access.\n\nClick the event link below to jump to the local_admin_analysis event and check: unexpected_accounts (local user accounts not on the allowed list), unexpected_profiles (C:\\Users profile directories not on the allowed list), bypass_nro (whether the BypassNRO registry flag was set), and confidence_score (the agent's confidence in the finding, 0-100).\n\nIf these accounts are expected for your environment (e.g. a service account or helpdesk account), add them to the allowed list in Tenant Settings.",
|
|
"remediation": [
|
|
{
|
|
"title": "Review the unexpected accounts",
|
|
"steps": [
|
|
"Open the session timeline and locate the local_admin_analysis event",
|
|
"Check the 'unexpected_accounts' and 'unexpected_profiles' lists in the event data",
|
|
"Verify whether these accounts are legitimate for your environment"
|
|
]
|
|
},
|
|
{
|
|
"title": "Add expected accounts to the allowed list (false positive)",
|
|
"steps": [
|
|
"Go to Settings → Agent Analyzers section",
|
|
"Under 'Allowed Admin Accounts', add the account names that are expected in your environment",
|
|
"Save the settings — future enrollments will no longer flag these accounts"
|
|
]
|
|
},
|
|
{
|
|
"title": "Investigate a potential security issue",
|
|
"steps": [
|
|
"Check if the BypassNRO registry flag was set (indicates OOBE was bypassed)",
|
|
"Review the enrollment timeline for Shift+F10 or other OOBE escape indicators",
|
|
"Check whether the unexpected account has admin group membership",
|
|
"Consider re-imaging the device if unauthorized admin access is confirmed"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [],
|
|
"tags": [
|
|
"identity",
|
|
"security",
|
|
"local-admin",
|
|
"bypass-detection"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ID-003",
|
|
"title": "Critical Vulnerability Detected",
|
|
"description": "Fires when the vulnerability correlation finds critical-severity CVEs or CISA KEV entries in installed software. This indicates the device has software with known, actively exploited vulnerabilities.",
|
|
"severity": "critical",
|
|
"category": "security",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 90,
|
|
"conditions": [
|
|
{
|
|
"signal": "critical_vulnerabilities",
|
|
"source": "event_type",
|
|
"eventType": "vulnerability_report",
|
|
"dataField": "scan_summary.critical_cves",
|
|
"operator": "gte",
|
|
"value": "1",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "kev_matches",
|
|
"source": "event_type",
|
|
"eventType": "vulnerability_report",
|
|
"dataField": "scan_summary.kev_matches",
|
|
"operator": "gte",
|
|
"value": "1",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "kev_matches",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"confidenceThreshold": 80,
|
|
"explanation": "The device has installed software with critical vulnerabilities. Software with CVEs rated CRITICAL (CVSS >= 9.0) or listed in the CISA Known Exploited Vulnerabilities catalog was detected. These vulnerabilities are actively targeted by attackers and should be remediated immediately.",
|
|
"remediation": [
|
|
{
|
|
"title": "Review vulnerability findings",
|
|
"steps": [
|
|
"Open the Vulnerability Report section in the session detail",
|
|
"Identify all software with critical or KEV-flagged vulnerabilities",
|
|
"Check if newer versions are available that address these CVEs",
|
|
"Update the affected software in your Intune app deployment"
|
|
]
|
|
},
|
|
{
|
|
"title": "Update deployment packages",
|
|
"steps": [
|
|
"Check Intune for outdated app package versions",
|
|
"Update the deployment package to the latest patched version",
|
|
"Re-deploy to affected devices"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "CISA KEV Catalog",
|
|
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog"
|
|
},
|
|
{
|
|
"title": "NVD - National Vulnerability Database",
|
|
"url": "https://nvd.nist.gov/"
|
|
}
|
|
],
|
|
"tags": [
|
|
"vulnerability",
|
|
"cve",
|
|
"kev",
|
|
"critical",
|
|
"security"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-ID-004",
|
|
"title": "Hybrid Sign-In Never Establishes Entra User Affinity",
|
|
"description": "On a hybrid-joined device the real user reached the desktop, but the Autopilot provisioning placeholder stayed active in JoinInfo and the agent repeatedly reported the hybrid sign-in as overdue. The user session never establishes Entra user affinity (no PRT), so the Account Setup ESP re-runs on every logon and the enrollment never completes.",
|
|
"severity": "high",
|
|
"category": "identity",
|
|
"version": "1.2.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"trigger": "correlation",
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"on_event:hybrid_login_pending"
|
|
],
|
|
"baseConfidence": 60,
|
|
"confidenceThreshold": 75,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "enrollment_complete",
|
|
"operator": "not_exists",
|
|
"description": "Suppress when the session eventually completed — a single overdue-login warning followed by a successful sign-in is normal hybrid latency, not a broken affinity."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "hybrid_login_overdue",
|
|
"source": "event_type",
|
|
"eventType": "hybrid_login_pending",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "user_desktop_reached",
|
|
"source": "event_type",
|
|
"eventType": "desktop_arrived",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "placeholder_still_active",
|
|
"source": "event_type",
|
|
"eventType": "aad_placeholder_user_detected",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "hybrid_login_pending",
|
|
"condition": "count >= 2",
|
|
"weight": 20
|
|
},
|
|
{
|
|
"signal": "hybrid_login_pending",
|
|
"condition": "count >= 3",
|
|
"weight": 10
|
|
},
|
|
{
|
|
"signal": "aad_placeholder_user_detected",
|
|
"condition": "count >= 3",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "A real user signed in and reached the desktop, but the device kept reporting the **Autopilot provisioning placeholder** as the active identity in JoinInfo and the hybrid sign-in as **overdue** — across multiple reboots. This means the signed-in user never established **Microsoft Entra user affinity** (no Primary Refresh Token), so:\n\n- the Account Setup ESP page re-appears on every logon,\n- user-targeted required apps and policies cannot settle,\n- the enrollment never reaches completion.\n\nAfter this many hours this is not normal Entra Connect sync latency — something is structurally preventing the user (or the computer object) from registering:\n\n- the computer object's `userCertificate` attribute is not syncing to Entra ID (sync scope / OU filtering),\n- the signing-in user is not synced, or their UPN does not match a verified Entra domain,\n- the device has no line of sight to a domain controller **at logon time**, so the hybrid PRT flow cannot finish,\n- time skew or a proxy blocking `login.microsoftonline.com` / `enterpriseregistration.windows.net` from the user context.\n\nA frequent variant: the user's **first sign-in happens without domain-controller reachability** — for example when a pre-logon VPN tunnel (GlobalProtect, Always On VPN, Zscaler ZPA) is not established yet at the logon screen. Windows falls back to cached credentials, the hybrid PRT flow silently never runs, and later reboots do not fix it — sessions in this state typically show repeated reboots and network flapping while the placeholder identity stays active.\n\nA visible side effect: **the Windows Hello for Business wizard never appears**, because Hello provisioning requires an Entra user token (PRT). Hello is a downstream symptom here, not the cause.",
|
|
"remediation": [
|
|
{
|
|
"title": "Verify user affinity on the device",
|
|
"steps": [
|
|
"Sign in as the affected user and run: dsregcmd /status — under 'SSO State' the value AzureAdPrt must be YES. NO means the user has no Entra token and this diagnosis is confirmed.",
|
|
"Also check 'Device State': AzureAdJoined = YES and DomainJoined = YES are expected for hybrid join.",
|
|
"Check Event Viewer: Applications and Services Logs > Microsoft > Windows > User Device Registration > Admin for PRT / registration errors (e.g. event 304/305/362).",
|
|
"Enable the gather rules 'Collect dsregcmd join status' so future sessions capture this state automatically."
|
|
]
|
|
},
|
|
{
|
|
"title": "Fix the identity pipeline",
|
|
"steps": [
|
|
"Entra Connect: confirm BOTH the computer OU and the user OU are in the sync scope, and the computer object's userCertificate attribute is being exported.",
|
|
"Verify the user's UPN suffix is a verified domain in Entra ID (no .local / mismatched suffix).",
|
|
"Ensure domain-controller line of sight at logon from the provisioning network/VLAN (hybrid PRT requires a reachable DC).",
|
|
"Check proxy/firewall rules for login.microsoftonline.com, device.login.microsoftonline.com and enterpriseregistration.windows.net from the user context."
|
|
]
|
|
},
|
|
{
|
|
"title": "Address VPN and Windows Hello dependencies",
|
|
"steps": [
|
|
"If a VPN is required to reach a domain controller, it must be established before or at the logon screen (machine tunnel / pre-logon tunnel). A user-context tunnel that starts after sign-in is too late for the hybrid PRT flow.",
|
|
"If you deploy Windows Hello for Business to hybrid-joined devices, use cloud Kerberos trust — it removes the on-premises certificate/key-trust dependencies that commonly stall Hello on hybrid devices.",
|
|
"If you do not use Windows Hello, disable it explicitly via a device-scoped Intune policy instead of leaving it unconfigured — the enrollment then resolves the Hello step deterministically instead of waiting for a wizard that never comes.",
|
|
"Avoid feature/quality updates mid-enrollment where possible — an OS update with forced reboots during enrollment aggravates this pattern. Consider a short Windows Update deferral covering the enrollment window.",
|
|
"For hybrid deployments, pre-provisioning (White Glove) materially shrinks the user-facing phase: the device phase runs on a known-good technician network, and the user phase reduces to sign-in, user ESP, and Hello."
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Autopilot Monitor: Hybrid join — stuck in Account Setup (no user affinity)",
|
|
"url": "https://docs.autopilotmonitor.com/troubleshooting/hybrid-join-stuck-in-account-setup"
|
|
},
|
|
{
|
|
"title": "Autopilot Monitor: Hybrid join — late device registration",
|
|
"url": "https://docs.autopilotmonitor.com/troubleshooting/hybrid-join-late-device-registration"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Troubleshoot hybrid-joined devices",
|
|
"url": "https://learn.microsoft.com/en-us/entra/identity/devices/troubleshoot-hybrid-join-windows-current"
|
|
}
|
|
],
|
|
"markSessionAsFailedDefault": false,
|
|
"tags": [
|
|
"identity",
|
|
"hybrid-join",
|
|
"entra-id",
|
|
"user-affinity",
|
|
"esp"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-OFFICE-001",
|
|
"title": "Microsoft 365 Apps Install Failed",
|
|
"description": "Detects when the Microsoft 365 Apps (Office Click-to-Run) background install did not reach completion. The V2 OfficeInstallDetector watches the C2R client directly (registry + process) and emits office_install_failed when the install scenario was abandoned (worker gone and streaming never finished) or a C2R failure code was observed. This catches Office failures that the Intune integrated app type hides, because IME reports the app done within 1-2 minutes while C2R keeps installing in the background.",
|
|
"severity": "warning",
|
|
"category": "apps",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 75,
|
|
"conditions": [
|
|
{
|
|
"signal": "office_install_failed",
|
|
"source": "event_type",
|
|
"eventType": "office_install_failed",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "error_code_present",
|
|
"source": "event_type",
|
|
"eventType": "office_install_failed",
|
|
"dataField": "errorCode",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "error_code_present",
|
|
"condition": "exists",
|
|
"weight": 15
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "The Microsoft 365 Apps (Office Click-to-Run) install did not finish.\n\nThe OfficeInstallDetector watches the C2R client directly and reports the real background install lifecycle. The Intune \"integrated\" Microsoft 365 Apps app type only pushes the configuration XML and starts the C2R bootstrapper, so IME marks the app done within 1-2 minutes while C2R keeps streaming and laying down the product for several more minutes. This event means C2R activity ended (the OfficeC2RClient worker exited and the install scenario cleared) without the StreamingFinished flag being set, or a C2R failure code was observed.\n\nReview the office_install_failed event payload: `products`, `channel`, `phase`, `streamingFinished`, `errorCode` (best-effort — may be empty) and `durationSeconds`.",
|
|
"remediation": [
|
|
{
|
|
"title": "Investigate the Office C2R install failure",
|
|
"steps": [
|
|
"Open the office_install_failed event and review products, channel, phase, streamingFinished and errorCode",
|
|
"Check the Click-to-Run logs on the device (%windir%\\Temp and %temp%, files named <MachineName>-yyyymmdd-nnnn.log) for the failing operation",
|
|
"Verify the device had network reachability to the Office CDN / Microsoft Connected Cache during the enrollment window",
|
|
"Confirm the Intune Microsoft 365 Apps app configuration (products, channel, architecture) matches what the device can install",
|
|
"Re-check the session timeline for a reboot or agent shutdown that may have interrupted the background C2R install"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"apps",
|
|
"office",
|
|
"microsoft-365-apps",
|
|
"click-to-run",
|
|
"install-failure"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-001",
|
|
"title": "Secure Boot UEFI CA 2023 certificate not deployed",
|
|
"description": "Detects devices where the Windows UEFI CA 2023 certificate has not been deployed to the Secure Boot DB. The 2011 certificates expired in June 2026 — affected devices no longer receive Secure Boot security updates until the 2023 certificate is deployed. Since v3 the agent reads the firmware db/KEK variables directly: when the firmware itself confirms the 2023 certificate, the rule is suppressed even if the Windows servicing status has not caught up yet.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "3.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 70,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "hardware_spec",
|
|
"dataField": "isVirtualMachine",
|
|
"operator": "equals",
|
|
"value": "false",
|
|
"description": "Skip on virtual machines — Secure Boot DB is host-controlled (Hyper-V/VMware/etc), the inside-the-VM UEFICA2023Status registry value is not the right indicator and not actionable for the VM admin."
|
|
},
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiCa2023FirmwareConfirmed",
|
|
"operator": "not_exists",
|
|
"value": "",
|
|
"description": "Skip when the firmware db itself confirms the Windows UEFI CA 2023 certificate — the marker is only emitted on positive firmware confirmation, so old agents (field absent) and unconfirmed devices keep evaluating the rule. The servicing registry status lags behind actual firmware state (OEM factory image, WinCS, manual deployment, or WU simply not run yet)."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "ca2023_not_updated",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiCA2023Status",
|
|
"operator": "not_equals",
|
|
"value": "Updated",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "secureboot_enabled",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiSecureBootEnabled",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "ca2023_notfound",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiCA2023Status",
|
|
"operator": "equals",
|
|
"value": "notfound",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "ca2023_error",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiCA2023Error",
|
|
"operator": "exists",
|
|
"value": "",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "db_ca2023_firmware_missing",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiDbHasWindowsUefiCa2023",
|
|
"operator": "equals",
|
|
"value": "false",
|
|
"required": false
|
|
},
|
|
{
|
|
"signal": "kek_2023_missing",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiKekHasMicrosoftKek2kCa2023",
|
|
"operator": "equals",
|
|
"value": "false",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "ca2023_notfound",
|
|
"condition": "exists",
|
|
"weight": 20
|
|
},
|
|
{
|
|
"signal": "ca2023_error",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
},
|
|
{
|
|
"signal": "db_ca2023_firmware_missing",
|
|
"condition": "exists",
|
|
"weight": 20
|
|
},
|
|
{
|
|
"signal": "kek_2023_missing",
|
|
"condition": "exists",
|
|
"weight": 10
|
|
}
|
|
],
|
|
"explanation": "This device has Secure Boot enabled but the **Windows UEFI CA 2023** certificate has not been deployed to the Secure Boot DB.\n\nThe original Windows UEFI CA 2011 certificates **expired on June 27, 2026 — this deadline has passed**. The automatic pre-expiry rollout window is over: this device no longer receives Secure Boot security updates (DB/DBX) and cannot trust 2023-signed boot managers until the 2023 certificate is deployed. Deploying it now requires active remediation (Windows servicing opt-in and, on some models, an OEM firmware update) rather than waiting for an automatic update.\n\nOn devices running a current agent this finding is verified against the firmware itself: the agent reads the UEFI `db` signature database directly, and this warning is automatically suppressed when the firmware already contains the 2023 certificate — regardless of the Windows servicing status below.\n\nCurrent UEFI CA 2023 servicing status: `{{uefiCA2023Status}}`",
|
|
"remediation": [
|
|
{
|
|
"title": "Deploy UEFI CA 2023 certificate now",
|
|
"steps": [
|
|
"Deploy KB5036210 via Windows Update or WSUS",
|
|
"Use Intune policy to enable Secure Boot DB update (Windows UEFI CA 2023)",
|
|
"Check with the device OEM whether a firmware update is required for the DB update to apply on this model",
|
|
"Alternatively, use the WinCS CLI tool from Microsoft for manual deployment",
|
|
"Verify deployment against the firmware directly: [Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI -Name db).Bytes).Contains('Windows UEFI CA 2023') — this is authoritative; the registry value HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\Servicing\\UEFICA2023Status = 'Updated' only reflects the Windows Update rollout",
|
|
"After DB update: ensure the boot manager is updated to a 2023-signed version via monthly cumulative update"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft: Secure Boot certificates expired June 2026 — act now",
|
|
"url": "https://techcommunity.microsoft.com/blog/windows-itpro-blog/act-now-secure-boot-certificates-expire-in-june-2026/4426856"
|
|
},
|
|
{
|
|
"title": "KB5036210: Deploying Windows UEFI CA 2023",
|
|
"url": "https://support.microsoft.com/en-us/topic/kb5036210"
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"secureboot",
|
|
"certificate",
|
|
"ca2023",
|
|
"compliance"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-003",
|
|
"title": "AutoLogon plaintext password stored in registry",
|
|
"description": "Fires when the AutoLogon analyzer reports a DefaultPassword value present in Winlogon. A plaintext AutoLogon password stored in the registry is readable by any local administrator and is a credential exposure — more severe than AutoLogon alone (the Sysinternals Autologon tool deliberately avoids this by storing the secret in the LSA instead).",
|
|
"severity": "high",
|
|
"category": "security",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 90,
|
|
"conditions": [
|
|
{
|
|
"signal": "default_password_present",
|
|
"source": "event_type",
|
|
"eventType": "autologon_analysis",
|
|
"dataField": "checks.default_password_present",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "This device has a **plaintext AutoLogon password stored in the registry** (`DefaultPassword` under `HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon`). This value is readable by any local administrator and exposes the AutoLogon account's credentials in clear text.\n\nEven when AutoLogon itself is intended (e.g. a kiosk), the password should never be left as a registry value. The Sysinternals Autologon tool stores the secret as an encrypted LSA secret precisely to avoid this; a plaintext `DefaultPassword` usually means a script or manual edit wrote the credentials directly.\n\nNote: the agent only reports the *presence* of this value — it never reads or transmits the password itself.",
|
|
"remediation": [
|
|
{
|
|
"title": "Remove the plaintext password",
|
|
"steps": [
|
|
"Delete the DefaultPassword value under HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
"If AutoLogon is still required, reconfigure it with the Sysinternals Autologon tool so the secret is stored as an encrypted LSA secret rather than a registry value",
|
|
"Rotate the exposed account's password, since it may have been readable on disk"
|
|
]
|
|
},
|
|
{
|
|
"title": "Reduce blast radius",
|
|
"steps": [
|
|
"Verify the AutoLogon account is the least-privileged account that satisfies the use case (not a domain or local admin where avoidable)",
|
|
"For kiosk scenarios, prefer Assigned Access / kiosk profiles over a raw AutoLogon credential"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Sysinternals Autologon (encrypted LSA-secret password storage)",
|
|
"url": "https://learn.microsoft.com/en-us/sysinternals/downloads/autologon"
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"autologon",
|
|
"winlogon",
|
|
"credentials",
|
|
"plaintext-password"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-004",
|
|
"title": "AutoLogon enabled for an unexpected user",
|
|
"description": "Optional kiosk allow-list for AutoLogon. Fires when AutoLogon is enabled for a default user that is NOT on your configured list of approved kiosk / shared-device accounts. Disabled until configured because a normal Autopilot enrollment leaves Windows' own ESP auto-logon for the enrolling user (AutoLogon enabled, a default user, no plaintext password) — so AutoLogon-enabled alone is not graded by default; only a plaintext DefaultPassword on disk (ANALYZE-SEC-003) is. Enable this rule with your expected kiosk account name(s) if you want to surface AutoLogon configured for any other user.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "1.1.0",
|
|
"enabled": false,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "autologon_enabled",
|
|
"source": "event_type",
|
|
"eventType": "autologon_analysis",
|
|
"dataField": "checks.autologon_enabled",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "unexpected_autologon_user",
|
|
"source": "event_data",
|
|
"eventType": "autologon_analysis",
|
|
"dataField": "checks.default_user_name",
|
|
"operator": "not_in",
|
|
"value": "EXPECTED-KIOSK-USER-1,EXPECTED-KIOSK-USER-2",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "AutoLogon is enabled on this device for a user that is **not on your approved kiosk allow-list**. AutoLogon is legitimate for kiosk and shared-device scenarios, so this rule only warns when the configured default user differs from the account(s) you expect.\n\nThis rule is **off by default**. A normal user-driven Autopilot enrollment leaves Windows' own ESP auto-logon for the enrolling user (`AutoAdminLogon=1`, a `DefaultUserName`, an `AutoLogonSID`, and no plaintext password) — registry-indistinguishable from a kiosk AutoLogon — so AutoLogon-enabled alone is not graded. The only AutoLogon state graded by default is a plaintext `DefaultPassword` on disk (**ANALYZE-SEC-003**).\n\nTo use this rule: configure the allow-list with your approved kiosk account name(s) (comma-separated, case-insensitive exact match against the Winlogon `DefaultUserName`) and enable it. AutoLogon for any other user will then warn.\n\nNote: an AutoLogon with no explicit default user (e.g. ForceAutoLogon only) is treated as unexpected and will warn.",
|
|
"remediation": [
|
|
{
|
|
"title": "Confirm the AutoLogon user",
|
|
"steps": [
|
|
"Open the autologon_analysis event in the session timeline and check the default user/domain",
|
|
"If the user is an approved kiosk account, add it to this rule's allow-list",
|
|
"If the user is unexpected, treat it as a possible enrollment/OOBE manipulation and investigate what wrote the Winlogon keys"
|
|
]
|
|
},
|
|
{
|
|
"title": "Disable AutoLogon if not required",
|
|
"steps": [
|
|
"Set HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\AutoAdminLogon to 0",
|
|
"Remove DefaultPassword (and any Sysinternals LSA secret) if present",
|
|
"For kiosk scenarios, prefer Assigned Access / kiosk profiles over raw AutoLogon where possible"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft: Configure Windows to automatically sign in (AutoLogon)",
|
|
"url": "https://learn.microsoft.com/en-us/troubleshoot/windows-server/user-profiles-and-logon/turn-on-automatic-logon"
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"autologon",
|
|
"winlogon",
|
|
"kiosk",
|
|
"allow-list"
|
|
],
|
|
"templateVariables": [
|
|
{
|
|
"name": "allowed_autologon_users",
|
|
"label": "Allowed AutoLogon users (kiosk accounts)",
|
|
"description": "Comma-separated list of approved kiosk / shared-device account names that are expected to use AutoLogon (case-insensitive exact match against the Winlogon DefaultUserName, e.g. 'KioskUser' or 'Reception,LobbyPC'). AutoLogon for any other user raises a warning.",
|
|
"conditionIndex": 1,
|
|
"field": "value",
|
|
"placeholder": "EXPECTED-KIOSK-USER-1,EXPECTED-KIOSK-USER-2"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-005",
|
|
"title": "Unexpected Provisioning Package",
|
|
"description": "Detects provisioning packages (PPKG) that are not on the built-in allow-list. The agent emits one or more provisioning_package_scan events whose artifacts[] arrays list every PPKG (registry package, .ppkg file, or Recovery\\Customizations residue; a large set is split across several events). This rule iterates that array across all of them and fires for any artifact whose identity does not match the allow-list regex. The default allow-list covers the Windows OS-inbox packages (Cosa, Power.EnergyEstimationEngine, Power.Settings, SecureStart) plus common OEM factory-preload families (Intel PPM power profiles, AMD Power profiles, Lenovo ThinkPad power/battery packages, Microsoft Surface defaults and carrier packages) so clean factory devices stay quiet. OEM imaging leftovers (e.g. USMT.PPKG, InstallOrder.ini) and generically named packages deliberately still alert — on a pure-Autopilot device they are worth a look. To allow your own vendor/recovery packages, enable the template rule ANALYZE-SEC-006, extend its allow-list, then disable this rule.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "2.2.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "ppkg_not_allowlisted",
|
|
"source": "event_data_array",
|
|
"eventType": "provisioning_package_scan",
|
|
"dataField": "artifacts",
|
|
"itemField": "identity",
|
|
"operator": "not_regex",
|
|
"value": "^(?:Microsoft\\.Windows\\.Cosa\\b|Power\\.EnergyEstimationEngine\\b|Power\\.Settings\\b|SecureStart\\.Settings\\b|PPM[-_]|PPMSettings-|AMD\\.Power\\.|TpPower|DisableBatteryDischargeEstimator\\b|PerfEppForBatterySaver\\b|AHSControl\\b|IRFeatureOptimization\\b|Surface[._]|vzw\\.ppkg\\b)",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "A provisioning package (PPKG) was detected that is NOT on the allow-list.\n\n- **Unexpected package:** `{{identity}}`\n\nThe agent reports every PPKG it finds in `provisioning_package_scan` event(s) (see their `artifacts` array(s) for the full list, plus file metadata and best-effort content indicators; large sets span several events). This rule ignores the Windows OS-inbox packages (Cosa, Power.EnergyEstimationEngine, Power.Settings, SecureStart) and the common OEM factory-preload families (Intel PPM power profiles, AMD Power profiles, Lenovo ThinkPad power/battery packages, Surface defaults and carrier packages) and only surfaces the rest. OEM imaging leftovers such as `USMT.PPKG` or `InstallOrder.ini` are deliberately NOT allow-listed — on a device expected to be freshly provisioned via Autopilot they indicate the image was touched by another deployment workflow.\n\nProvisioning packages can apply local accounts, certificates, Wi-Fi/VPN profiles, applications (MSI/EXE) and scripts. They are legitimate in bulk-enrollment and OEM-recovery scenarios, but a PPKG appearing on a device that is expected to be \"pure Autopilot\" can indicate tampering.\n\n**To stop alerting on a known-good package:** enable the template rule **ANALYZE-SEC-006**, add the package to its allow-list regex, then disable this rule. ANALYZE-SEC-006 then only fires for packages outside your extended allow-list.",
|
|
"remediation": [
|
|
{
|
|
"title": "Verify the provisioning package is expected",
|
|
"steps": [
|
|
"Open the provisioning_package_scan event and review the artifacts array (identity, source, file path, ownerType/installTime for registry packages)",
|
|
"Confirm whether the package matches a known source: bulk-enrollment PPKG, OEM recovery package, or an internal provisioning workflow",
|
|
"Cross-check the device model/vendor — OEM recovery PPKGs are common and usually benign",
|
|
"If the package is unexpected for a pure-Autopilot device, treat it as a potential manipulation and investigate how it was applied (USB, Recovery\\Customizations, image)",
|
|
"To allow known-good packages going forward, enable ANALYZE-SEC-006, extend the allow-list, then disable this rule"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"provisioning-package",
|
|
"ppkg",
|
|
"allow-list",
|
|
"tamper"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-006",
|
|
"title": "Unexpected Provisioning Package (Custom Allow-List)",
|
|
"description": "Template version of ANALYZE-SEC-005 with a customizable allow-list. Iterates the provisioning_package_scan artifacts[] array and fires for any PPKG whose identity is not on YOUR allow-list regex. The placeholder ships with the same OS-inbox defaults as ANALYZE-SEC-005 — extend it with your own vendor/recovery packages. This rule is OFF by default: enable it, set your allow-list, then disable ANALYZE-SEC-005 so only packages outside your list alert.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "2.2.0",
|
|
"enabled": false,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "ppkg_not_allowlisted",
|
|
"source": "event_data_array",
|
|
"eventType": "provisioning_package_scan",
|
|
"dataField": "artifacts",
|
|
"itemField": "identity",
|
|
"operator": "not_regex",
|
|
"value": "^(?:Microsoft\\.Windows\\.Cosa\\b|Power\\.EnergyEstimationEngine\\b|Power\\.Settings\\b|SecureStart\\.Settings\\b|PPM[-_]|PPMSettings-|AMD\\.Power\\.|TpPower|DisableBatteryDischargeEstimator\\b|PerfEppForBatterySaver\\b|AHSControl\\b|IRFeatureOptimization\\b|Surface[._]|vzw\\.ppkg\\b)",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "A provisioning package (PPKG) was detected whose identity is NOT on your configured allow-list.\n\n- **Unexpected package:** `{{identity}}`\n\nThe `identity` value combines a package's name, .ppkg file name, ownerType and packageId, so your allow-list regex can match an approved package by any of these. The default allow-list already covers the Windows OS-inbox packages (Cosa, Power.EnergyEstimationEngine, Power.Settings, SecureStart) and the common OEM factory-preload families (Intel PPM, AMD Power, Lenovo ThinkPad power/battery, Surface defaults and carrier packages) — extend it with your own vendor/recovery packages.\n\nIf this package should be allowed, add it to the allow-list regex (the 'value' of the 'ppkg_not_allowlisted' condition). If it is genuinely unexpected on a pure-Autopilot device, treat it as a potential manipulation and investigate how it was applied.",
|
|
"remediation": [
|
|
{
|
|
"title": "Triage the unexpected package",
|
|
"steps": [
|
|
"Open the provisioning_package_scan event and review the artifacts array for this package's identity and source",
|
|
"Decide: is this a known-good package that should be allow-listed, or genuinely unexpected?",
|
|
"If known-good: the allow-list is anchored (^(?:...)\\b), so insert a new alternative INSIDE the group, before the closing ')' — e.g. ...|SecureStart\\.Settings|Acme\\.Recovery)\\b. Appending after the ) or \\b will not match.",
|
|
"If unexpected: investigate the application path (USB media, C:\\Recovery\\Customizations residue, custom image) and the device's chain of custody"
|
|
]
|
|
},
|
|
{
|
|
"title": "Activate the custom allow-list workflow (2-step)",
|
|
"steps": [
|
|
"Enable this rule and extend the allow-list regex by inserting your approved packages as alternatives inside the anchored group (before the closing ')'), case-insensitive",
|
|
"Verify it behaves as expected on a known device",
|
|
"Disable the built-in rule ANALYZE-SEC-005 so only packages outside your allow-list alert going forward"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"provisioning-package",
|
|
"ppkg",
|
|
"allow-list",
|
|
"template"
|
|
],
|
|
"templateVariables": [
|
|
{
|
|
"name": "allowed_packages",
|
|
"label": "Allowed provisioning packages (regex)",
|
|
"description": "Case-insensitive regex matched against each package's identity (name | fileName | ownerType | packageId). Packages matching this pattern are treated as approved and do NOT alert. The default is anchored (^...) so it matches only at the START of the identity — extend it by adding an alternative inside the group, e.g. add '|Acme\\.Recovery' before the closing ')'.",
|
|
"conditionIndex": 0,
|
|
"field": "value",
|
|
"placeholder": "^(?:Microsoft\\.Windows\\.Cosa\\b|Power\\.EnergyEstimationEngine\\b|Power\\.Settings\\b|SecureStart\\.Settings\\b|PPM[-_]|PPMSettings-|AMD\\.Power\\.|TpPower|DisableBatteryDischargeEstimator\\b|PerfEppForBatterySaver\\b|AHSControl\\b|IRFeatureOptimization\\b|Surface[._]|vzw\\.ppkg\\b)"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-007",
|
|
"title": "Provisioning Package Scan Incomplete",
|
|
"description": "Fires when the provisioning-package scan hit a per-source collection cap (too many .ppkg files, registry packages, or Recovery\\Customizations residue files to capture them all). When that happens the allow-list rules (ANALYZE-SEC-005/006) could not evaluate every package, so a non-allow-listed package may have gone unseen. A device with that many provisioning packages is itself unusual and worth a manual look.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "1.1.0",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"baseConfidence": 80,
|
|
"conditions": [
|
|
{
|
|
"signal": "ppkg_scan_truncated",
|
|
"source": "event_data",
|
|
"eventType": "provisioning_package_scan",
|
|
"dataField": "scanTruncated",
|
|
"operator": "equals",
|
|
"value": "true",
|
|
"required": true
|
|
}
|
|
],
|
|
"confidenceThreshold": 40,
|
|
"explanation": "The provisioning-package scan was incomplete: the device had more provisioning packages than the agent captures per source, so a per-source cap was hit (see `ppkgFilesTruncated` / `packagesTruncated` / `recoveryFilesTruncated` on the `provisioning_package_scan` event).\n\nBecause not every package was captured, the allow-list rules (ANALYZE-SEC-005/006) may NOT have evaluated all of them — a non-allow-listed package could be present but unseen. A device carrying this many provisioning packages is also unusual on its own and warrants a manual review.",
|
|
"remediation": [
|
|
{
|
|
"title": "Review the device manually",
|
|
"steps": [
|
|
"Open the provisioning_package_scan event and check which counts exceeded the cap (ppkgFileCount / packageCount vs the *Truncated flags)",
|
|
"Inspect the device directly: C:\\ProgramData\\Microsoft\\Provisioning, C:\\Windows\\Provisioning, C:\\Recovery\\Customizations, and HKLM\\SOFTWARE\\Microsoft\\Provisioning\\Packages",
|
|
"Confirm whether the large number of provisioning packages is expected for this device/model (e.g. an OEM image) or anomalous",
|
|
"If anomalous, treat it as a potential manipulation and investigate the device's chain of custody"
|
|
]
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"provisioning-package",
|
|
"ppkg",
|
|
"truncated",
|
|
"coverage"
|
|
]
|
|
},
|
|
{
|
|
"ruleId": "ANALYZE-SEC-008",
|
|
"title": "Secure Boot is disabled",
|
|
"description": "Detects devices enrolling with Secure Boot turned off. Secure Boot is a firmware-level protection against boot-time malware and is a prerequisite for several Windows security features (VBS/Credential Guard, device health attestation) and common Intune compliance policies. Devices that support Secure Boot but have it disabled should be flagged during enrollment. Legacy BIOS devices (no Secure Boot capability) are excluded — the agent marks those with a note field when the SecureBoot registry state key is absent.",
|
|
"severity": "warning",
|
|
"category": "security",
|
|
"version": "1.1.0",
|
|
"author": "Autopilot Monitor",
|
|
"enabled": true,
|
|
"evaluateOn": [
|
|
"enrollment_end",
|
|
"whiteglove_sealed"
|
|
],
|
|
"trigger": "single",
|
|
"baseConfidence": 70,
|
|
"preconditions": [
|
|
{
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "note",
|
|
"operator": "not_exists",
|
|
"value": "",
|
|
"description": "Skip when the agent could not find the SecureBoot state registry key (note field set) — that indicates a legacy BIOS / non-UEFI device where Secure Boot is unsupported rather than disabled, so a warning would not be actionable."
|
|
}
|
|
],
|
|
"conditions": [
|
|
{
|
|
"signal": "secureboot_disabled",
|
|
"source": "event_data",
|
|
"eventType": "secureboot_status",
|
|
"dataField": "uefiSecureBootEnabled",
|
|
"operator": "equals",
|
|
"value": "false",
|
|
"required": true
|
|
},
|
|
{
|
|
"signal": "physical_device",
|
|
"source": "event_data",
|
|
"eventType": "hardware_spec",
|
|
"dataField": "isVirtualMachine",
|
|
"operator": "equals",
|
|
"value": "false",
|
|
"required": false
|
|
}
|
|
],
|
|
"confidenceFactors": [
|
|
{
|
|
"signal": "physical_device",
|
|
"condition": "exists",
|
|
"weight": 20
|
|
}
|
|
],
|
|
"confidenceThreshold": 60,
|
|
"explanation": "This device enrolled with **Secure Boot disabled**.\n\nThe firmware reports UEFI mode, but Secure Boot is turned off (`HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State\\UEFISecureBootEnabled = 0`). Without Secure Boot the boot chain is not verified, which:\n\n- Leaves the device exposed to bootkits and unsigned boot-time code\n- Blocks or weakens Virtualization-based Security (VBS), Credential Guard and Device Health Attestation\n- Typically makes the device **non-compliant** if an Intune compliance policy requires Secure Boot — Conditional Access may then block the user right after enrollment\n\nSecure Boot is usually disabled deliberately in firmware setup (e.g. for imaging, dual-boot or legacy CSM mode) and simply never re-enabled before the device was handed to Autopilot.",
|
|
"remediation": [
|
|
{
|
|
"title": "Enable Secure Boot in UEFI firmware",
|
|
"steps": [
|
|
"Reboot into the UEFI firmware setup (typically F2/F10/F12/Del during boot, or Shift+Restart -> Troubleshoot -> UEFI Firmware Settings)",
|
|
"Disable Legacy/CSM boot mode if it is active — Secure Boot requires native UEFI boot",
|
|
"Enable Secure Boot and ensure the Microsoft UEFI CA keys are selected (factory default key set)",
|
|
"Save, reboot and verify in Windows: msinfo32 -> 'Secure Boot State' = On, or PowerShell Confirm-SecureBootUEFI returns True",
|
|
"For Hyper-V test VMs: use a Generation 2 VM and enable Secure Boot in the VM's Security settings (template 'Microsoft Windows')"
|
|
]
|
|
},
|
|
{
|
|
"title": "Check compliance impact",
|
|
"steps": [
|
|
"Review Intune compliance policies assigned to this device for a 'Require Secure Boot' setting",
|
|
"If the device stays non-compliant, Conditional Access policies may block sign-in — fix firmware settings before user handover"
|
|
]
|
|
}
|
|
],
|
|
"relatedDocs": [
|
|
{
|
|
"title": "Microsoft Learn: Secure Boot",
|
|
"url": "https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-secure-boot"
|
|
},
|
|
{
|
|
"title": "Microsoft Learn: Re-enable Secure Boot",
|
|
"url": "https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/disabling-secure-boot"
|
|
}
|
|
],
|
|
"tags": [
|
|
"security",
|
|
"secureboot",
|
|
"firmware",
|
|
"uefi",
|
|
"compliance"
|
|
]
|
|
}
|
|
]
|
|
}
|