fix(rules): surface detection-failure root cause in analyze pipeline

Session 080edee9 fired only ANALYZE-ENRL-001 ("Enrollment Failed") with a
generic explanation, even though we already had all the data to point at
the specific failed app (Microsoft Apps for Enterprise) and the specific
HRESULT (0x87D1041C - Intune detection rule mismatch). Three coordinated
rule changes close that enrichment gap:

ANALYZE-APP-001 (Win32 App Detection Script Failure):
  Switch from a regex on the `message` field (which never matched the
  agent's "Install status unconfirmed - ESP timed out" wording) to a
  direct check on `dataField: detectionResult, operator: equals,
  value: NotDetected`. The rule engine already supports nested DataJson
  fields on `event_type` conditions, so this is the right shape and the
  rule now fires whenever the IME reported a detection-rule mismatch.

ANALYZE-APP-013 (App Detection Failure During ESP - 0x87D1041C, new):
  Matches the canonical `failureType: esp_apps_detection_failure` tag
  emitted by the V2 agent's new classifier. Severity=critical, baseConf=90.
  Pulls failed appName + HRESULT into the explanation via the existing
  `{{token}}` interpolator, and ships a three-step remediation plan:
  (1) validate the detection rule against an installed reference device,
  (2) investigate post-install async tasks (the install may complete only
  after ESP's detection probe runs), (3) cross-check the per-app event's
  detectionResult + bytesDownloaded + hresultFromWin32.

ANALYZE-ENRL-001 (Enrollment Failed):
  Add optional conditions that capture {reason, failedSubcategory, errorCode,
  failedApp.appName} into MatchedConditions so the explanation can resolve
  `{{reason}}` / `{{failedSubcategory}}` / `{{errorCode}}` / `{{appName}}`
  via the existing `interpolateRuleTemplate` engine. Remediation text now
  cross-references ANALYZE-APP-* rules for the actionable root cause.

dist regenerated via `node rules/scripts/combine.js` (25 -> 26 rules).
Backend embeds dist/analyze-rules.json as a resource; next deploy picks up
the new content automatically.

Coverage: 2058/2058 backend tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Oliver Kieselbach
2026-05-28 13:41:48 +02:00
parent 140b1dc317
commit db7ca6ed87
4 changed files with 243 additions and 10 deletions
+3 -3
View File
@@ -12,9 +12,9 @@
"signal": "detection_failure",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "message",
"operator": "regex",
"value": "detection|not detected|script.*fail|detection.*error|DetectionState|NotDetected",
"dataField": "detectionResult",
"operator": "equals",
"value": "NotDetected",
"required": true
}
],
+74
View File
@@ -0,0 +1,74 @@
{
"$schema": "../schema/analyze-rule.schema.json",
"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",
"enabled": true,
"baseConfidence": 90,
"conditions": [
{
"signal": "esp_apps_detection_failure",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "failureType",
"operator": "equals",
"value": "esp_apps_detection_failure",
"required": true
},
{
"signal": "failed_app_name",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "appName",
"operator": "exists",
"value": "",
"required": false
},
{
"signal": "detection_hresult",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "errorCode",
"operator": "exists",
"value": "",
"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"]
}
+39 -2
View File
@@ -15,17 +15,54 @@
"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": "app_failed", "condition": "exists", "weight": 5 }
],
"explanation": "The Autopilot enrollment has explicitly failed. Check the enrollment_failed event details and other rule results for the root cause.",
"explanation": "The Autopilot enrollment has explicitly failed. The most specific failure information is carried by the events captured during this session — review the `enrollment_failed` event payload and the more targeted rule results (ANALYZE-APP-* / ANALYZE-ESP-*) that fired alongside this one for the actionable root cause.\n\nKey facts extracted from the timeline:\n\n- **Failure reason:** `{{reason}}`\n- **ESP failed subcategory:** `{{failedSubcategory}}`\n- **ESP HRESULT:** `{{errorCode}}`\n- **First failed app:** `{{appName}}`\n\n(Fields shown as `{{…}}` were not present in this session — e.g. a non-ESP failure path has no failed-subcategory, and a successful pre-ESP stage has no failed app.)",
"remediation": [
{
"title": "Investigate enrollment failure",
"steps": [
"Check the 'reason' field in the enrollment_failed event for specific failure details",
"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) — the ANALYZE-APP-* rules in this session correlate specific HRESULTs to actionable root causes (e.g. 0x87D1041C → detection rule mismatch)",
"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"
+127 -5
View File
@@ -14,9 +14,9 @@
"signal": "detection_failure",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "message",
"operator": "regex",
"value": "detection|not detected|script.*fail|detection.*error|DetectionState|NotDetected",
"dataField": "detectionResult",
"operator": "equals",
"value": "NotDetected",
"required": true
}
],
@@ -499,6 +499,91 @@
"resolved"
]
},
{
"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",
"enabled": true,
"baseConfidence": 90,
"conditions": [
{
"signal": "esp_apps_detection_failure",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "failureType",
"operator": "equals",
"value": "esp_apps_detection_failure",
"required": true
},
{
"signal": "failed_app_name",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "appName",
"operator": "exists",
"value": "",
"required": false
},
{
"signal": "detection_hresult",
"source": "event_type",
"eventType": "app_install_failed",
"dataField": "errorCode",
"operator": "exists",
"value": "",
"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-CORR-001",
"title": "Slow Network Causing App Installation Failure",
@@ -889,6 +974,42 @@
"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": [
@@ -898,12 +1019,13 @@
"weight": 5
}
],
"explanation": "The Autopilot enrollment has explicitly failed. Check the enrollment_failed event details and other rule results for the root cause.",
"explanation": "The Autopilot enrollment has explicitly failed. The most specific failure information is carried by the events captured during this session — review the `enrollment_failed` event payload and the more targeted rule results (ANALYZE-APP-* / ANALYZE-ESP-*) that fired alongside this one for the actionable root cause.\n\nKey facts extracted from the timeline:\n\n- **Failure reason:** `{{reason}}`\n- **ESP failed subcategory:** `{{failedSubcategory}}`\n- **ESP HRESULT:** `{{errorCode}}`\n- **First failed app:** `{{appName}}`\n\n(Fields shown as `{{…}}` were not present in this session — e.g. a non-ESP failure path has no failed-subcategory, and a successful pre-ESP stage has no failed app.)",
"remediation": [
{
"title": "Investigate enrollment failure",
"steps": [
"Check the 'reason' field in the enrollment_failed event for specific failure details",
"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) — the ANALYZE-APP-* rules in this session correlate specific HRESULTs to actionable root causes (e.g. 0x87D1041C → detection rule mismatch)",
"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"