Skip to content

feat: add Defender KEV version compliance remediation#3

Open
Thugney wants to merge 1 commit into
mainfrom
feat/defender-kev-version-compliance-remediation
Open

feat: add Defender KEV version compliance remediation#3
Thugney wants to merge 1 commit into
mainfrom
feat/defender-kev-version-compliance-remediation

Conversation

@Thugney

@Thugney Thugney commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Adds a public-safe Intune Proactive Remediation pair for Microsoft Defender Antivirus engine/platform version compliance.

Why this is worth adding:

  • Based on an existing private toolkit pattern, sanitized for public sharing.
  • Supports a practical Defender/Intune field note: detect version drift, trigger Defender update mechanisms, and validate before/after evidence.
  • Detection is read-only; remediation only triggers Microsoft Defender update mechanisms.
  • Minimum versions are intentionally configurable and documented.

Files:

  • intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1
  • intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1
  • intune/remediations/defender-kev-version-compliance/README.md

Public safety:

  • No tenant names, hostnames, users, device names, policy names, group names, or exact fleet details.
  • Generic Defender version compliance wording.

Summary by CodeRabbit

  • New Features

    • Added Intune Proactive Remediation scripts for detecting and enforcing Microsoft Defender Antivirus engine and platform version compliance with automatic remediation capabilities.
  • Documentation

    • Added documentation for the Defender version compliance remediation pair, including configuration and deployment guidance.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Three new files are added under intune/remediations/defender-kev-version-compliance/: a detection script that reads Defender engine/platform versions and exits noncompliant (1) when below configured minimums, a remediation script that triggers signature updates and re-evaluates versions, and a README documenting both scripts.

Changes

Defender KEV Version Compliance Remediation Pair

Layer / File(s) Summary
Detection script: config, logging, and compliance check
intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1
Defines log paths and configurable minimum Defender engine/platform versions; adds Write-Log helper for timestamped UTF-8 file logging; implements main detection flow using Get-MpComputerStatus to compare versions against minimums and exit 0 (compliant) or 1 (noncompliant); wraps execution in a top-level try/catch that exits 1 on any error.
Remediation script: config, helpers, update flow, and README
intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1, intune/remediations/defender-kev-version-compliance/README.md
Defines the same configurable minimum versions and log paths; adds Write-Log and Get-DefenderVersionState helpers; implements the remediation flow logging before/after versions, running Update-MpSignature then MpCmdRun.exe -SignatureUpdate, waiting, and evaluating post-update compliance to decide exit code 0 vs 1; adds full README covering script purposes, version variables, Intune settings, safety notes, and documentation links.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hop hop, the rabbit checks each version with care,
Engine and platform must meet the bar set there.
If Defender's behind, the remediation runs,
MpCmdRun.exe fired like tiny starter guns.
Logs are written, exit codes declared,
Compliance enforced — no endpoint left unpaired! 🛡️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a Defender KEV version compliance remediation feature. It is concise, clear, and directly reflects the primary objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/defender-kev-version-compliance-remediation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1 (1)

38-61: ⚡ Quick win

Shared root cause: both scripts define Write-Log, which risks cmdlet shadowing and inconsistent behavior across PowerShell environments.

  • intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1#L38-L61: rename the helper to a non-cmdlet name (for example Write-ScriptLog) and update all call sites in this file.
  • intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1#L38-L61: apply the same rename to keep the pair consistent and avoid cross-script drift.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1`
around lines 38 - 61, The Write-Log function defined in both scripts risks
cmdlet shadowing and creates inconsistent behavior. Rename the function from
Write-Log to Write-ScriptLog in both affected files to avoid conflicts with
PowerShell's built-in cmdlets. In
intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1
(lines 38-61), rename the function definition from Write-Log to Write-ScriptLog
and update all call sites in this file that invoke Write-Log. In
intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1
(lines 38-61), apply the identical rename to keep the pair consistent and
prevent cross-script drift.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1`:
- Around line 88-100: The MpCmdRun.exe lookup in the remediation script is
incomplete and only checks the legacy location at $env:ProgramFiles\Windows
Defender\MpCmdRun.exe, missing the platform-serviced installation path. Modify
the code before the Test-Path check on line 88 to search for MpCmdRun.exe in
both locations: first attempt to locate it at $env:ProgramData\Microsoft\Windows
Defender\Platform\<version>\MpCmdRun.exe (the recommended platform-serviced
path), then fall back to the legacy $env:ProgramFiles\Windows
Defender\MpCmdRun.exe location. Ensure the script uses whichever path is found,
allowing it to successfully update signatures on endpoints using the newer
platform-serviced Defender installation.

---

Nitpick comments:
In
`@intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1`:
- Around line 38-61: The Write-Log function defined in both scripts risks cmdlet
shadowing and creates inconsistent behavior. Rename the function from Write-Log
to Write-ScriptLog in both affected files to avoid conflicts with PowerShell's
built-in cmdlets. In
intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1
(lines 38-61), rename the function definition from Write-Log to Write-ScriptLog
and update all call sites in this file that invoke Write-Log. In
intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1
(lines 38-61), apply the identical rename to keep the pair consistent and
prevent cross-script drift.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2aa02a13-1c8b-4ce2-8455-a5ad6a0d6a88

📥 Commits

Reviewing files that changed from the base of the PR and between 22299ab and cc3ae24.

📒 Files selected for processing (3)
  • intune/remediations/defender-kev-version-compliance/Detect-DefenderKevVersionCompliance.ps1
  • intune/remediations/defender-kev-version-compliance/README.md
  • intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1

Comment on lines +88 to +100
$MpCmdRun = Join-Path -Path $env:ProgramFiles -ChildPath 'Windows Defender\MpCmdRun.exe'
if (Test-Path -Path $MpCmdRun) {
try {
Write-Log -Message 'Running MpCmdRun signature update.'
Start-Process -FilePath $MpCmdRun -ArgumentList '-SignatureUpdate' -Wait -NoNewWindow -ErrorAction Stop
}
catch {
Write-Log -Message ('MpCmdRun signature update failed: {0}' -f $_.Exception.Message) -Level WARNING
}
}
else {
Write-Log -Message ('MpCmdRun not found at {0}' -f $MpCmdRun) -Level WARNING
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What are the documented/typical install locations of Microsoft Defender MpCmdRun.exe on current Windows versions, including platform-serviced paths?

💡 Result:

On current Windows versions, the Microsoft Defender command-line utility, MpCmdRun.exe, is documented to reside in two primary locations [1][2]. 1. C:\Program Files\Windows Defender 2. C:\ProgramData\Microsoft\Windows Defender\Platform<antimalware platform version>\ The path C:\ProgramData\Microsoft\Windows Defender\Platform<antimalware platform version> (often referred to as the platform-serviced path) is the recommended location [1][2]. Microsoft advises that the latest version of the utility is always available within this folder if it exists on the system [1][2]. Because these directories are not included in the system PATH environment variable by default, you must navigate to the directory or use the full path to execute the file [1][2]. Microsoft provides an official script snippet to programmatically identify and switch to the most current version of the utility: (set "_done=" & if exist "%ProgramData%\Microsoft\Windows Defender\Platform" (for /f "delims=" %d in ('dir "%ProgramData%\Microsoft\Windows Defender\Platform" /ad /b /o:-n 2^>nul') do if not defined _done (cd /d "%ProgramData%\Microsoft\Windows Defender\Platform%d" & set _done=1)) else (cd /d "%ProgramFiles%\Windows Defender")) >nul 2>&1 [1][2] This approach is the standard practice for ensuring that scripts and automated tasks interact with the most recent, serviced version of the Defender platform [1][2][3].

Citations:


MpCmdRun.exe lookup is incomplete and misses platform-serviced Defender installations.

Line 88 only checks $env:ProgramFiles\Windows Defender\MpCmdRun.exe. Microsoft documents two primary locations for MpCmdRun.exe: the legacy Program Files\Windows Defender directory and the platform-serviced path at $env:ProgramData\Microsoft\Windows Defender\Platform\<version>\MpCmdRun.exe. The platform path is the recommended location and contains the latest serviced version. On many endpoints, this causes the script to skip the signature update and reduces remediation success rates.

Suggested diff
-    $MpCmdRun = Join-Path -Path $env:ProgramFiles -ChildPath 'Windows Defender\MpCmdRun.exe'
-    if (Test-Path -Path $MpCmdRun) {
+    $MpCmdRunCandidates = @(
+        (Join-Path -Path $env:ProgramFiles -ChildPath 'Windows Defender\MpCmdRun.exe'),
+        (Get-ChildItem -Path "$env:ProgramData\Microsoft\Windows Defender\Platform" -Directory -ErrorAction SilentlyContinue |
+            Sort-Object Name -Descending |
+            ForEach-Object { Join-Path -Path $_.FullName -ChildPath 'MpCmdRun.exe' } |
+            Select-Object -First 1)
+    ) | Where-Object { $_ -and (Test-Path -Path $_) }
+
+    $MpCmdRun = $MpCmdRunCandidates | Select-Object -First 1
+    if ($MpCmdRun) {
         try {
             Write-Log -Message 'Running MpCmdRun signature update.'
             Start-Process -FilePath $MpCmdRun -ArgumentList '-SignatureUpdate' -Wait -NoNewWindow -ErrorAction Stop
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@intune/remediations/defender-kev-version-compliance/Remediate-DefenderKevVersionCompliance.ps1`
around lines 88 - 100, The MpCmdRun.exe lookup in the remediation script is
incomplete and only checks the legacy location at $env:ProgramFiles\Windows
Defender\MpCmdRun.exe, missing the platform-serviced installation path. Modify
the code before the Test-Path check on line 88 to search for MpCmdRun.exe in
both locations: first attempt to locate it at $env:ProgramData\Microsoft\Windows
Defender\Platform\<version>\MpCmdRun.exe (the recommended platform-serviced
path), then fall back to the legacy $env:ProgramFiles\Windows
Defender\MpCmdRun.exe location. Ensure the script uses whichever path is found,
allowing it to successfully update signatures on endpoints using the newer
platform-serviced Defender installation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant