Quick Answer: To force-update Microsoft Defender Antivirus platform and security intelligence to the latest version using PowerShell, run the script below as SYSTEM via Intune Remediation or a Scheduled Task. The script registers the Microsoft Update service directly (bypassing WSUS), downloads and installs pending Defender platform updates (KB4052623), updates security intelligence with a fallback chain, and verifies success with distinct exit codes. No hard-coded versions. No manual downloads.
Why Defender Falls Behind and Why Update-MpSignature Alone Is Not Enough
You open the Intune compliance dashboard and see it: “Update Microsoft Defender to version 1.1.26080.3” flagged as a zero-day security update. The device shows non-compliant. Your instinct is to run Update-MpSignature and move on.
Intune compliance flagging a pending Defender zero-day security update.
Here is the problem. Update-MpSignature only updates security intelligence (definitions) and the engine. It does not touch the Defender platform (the AMProductVersion value you see under Get-MpComputerStatus). The platform update ships as a separate Windows Update package under KB4052623, and it requires the Windows Update Agent COM API to install.
On WSUS-managed or SCCM co-managed devices, the situation gets worse. If the WSUS admin has not approved KB4052623, the device will never receive the platform update through standard channels. The device stays non-compliant indefinitely.
How Microsoft Defender Updates Work Normally (Without Scripts)
In a healthy enterprise environment, you should not need a script to update Defender on every machine. Microsoft Defender Antivirus is engineered to maintain itself autonomously across three distinct update layers:
Update Component
What It Protects
Standard Update Mechanism
Default Cadence
Security Intelligence (Signatures)
Known malware hashes, heuristic rules, dynamic cloud signatures
Internal Defender background service checks Microsoft Cloud / MMPC directly
Every 2 to 4 hours
Antimalware Engine
Scanning and detection logic parsing files and memory
Bundled with security intelligence updates and monthly platform rollouts
Monthly
Antimalware Platform (KB4052623)
Core protection service (MsMpEng.exe), drivers, and network inspection
Windows Update / Windows Server Update Services (WSUS)
Monthly (Current Channel Broad)
Enterprise administrators typically control this behavior natively through Microsoft Intune and policy baselines using two primary methods:
Under Endpoint security > Antivirus > Microsoft Defender Antivirus policy, Microsoft provides dedicated Defender Update Controls. These allow you to assign release channels for each component without writing code:
Beta Channel: Earliest validation for non-production lab rings.
Preview Channel: Early validation ring (ideal for IT pilot groups).
Staged Channel: Deployed gradually after preview validation.
Broad Channel: Production general rollout (recommended for 90%+ of fleet).
Configuring Engine, Platform, and Security Intelligence Update Channels in Microsoft Intune Defender Antivirus policy.
2. Windows Update for Business (WUfB) Update Rings
Because the core platform (KB4052623) is distributed as a Windows Update package, healthy cloud-managed endpoints receive it automatically during their normal Windows Update check cycle, adhering to quality update deferral and maintenance windows.
When Do You Actually Need a PowerShell Remediation Script?
If Microsoft designed Defender to update itself, why does this script exist? Because in large enterprise fleets, 5% to 10% of devices inevitably fall out of the standard pipeline. When that happens, compliance fails, zero-day vulnerabilities remain exposed, and standard portal buttons cannot force the update.
Here is a breakdown of when native automation works versus when this remediation script is required:
Operational Scenario
Why Built-in Update Channels Fail
Requires Remediation Script?
Standard Managed Device
Device is online, healthy, and receives monthly Windows Updates normally.
No — Native Intune / WUfB channels handle this automatically.
WSUS Approval Bottlenecks
The device points to internal WSUS/SCCM where the security team or admin hasn’t approved KB4052623.
Yes — Script directly contacts Microsoft Update cloud and bypasses internal WSUS locks.
Corrupted Defender State
WMI or Defender service crashed; AMEngineVersion shows 0.0.0.0 and protection is “Not Running”.
Yes — Script kicks the service, forces fresh platform reinstallation, and reinitializes protection.
Post-Migration from 3rd-Party AV
Uninstalling a third-party AV (CrowdStrike, SentinelOne, Symantec) leaves Defender in passive or broken state.
Yes — Forces signature download, starts engine, and confirms active RTP status.
Stale / Offline Laptops
Field laptops powered off for 30+ days miss intermediate prerequisite signature builds.
Yes — Script executes fallback chain (Microsoft Update → MMPC) to catch up instantly.
Disabled Windows Update Service
Third-party “debloater” scripts or rogue GPOs set wuauserv to Disabled.
Yes — Script restores wuauserv to Manual, runs update, and restores original state.
Architecture Tip: Do not deploy the remediation script as a mandatory Win32 app or run it unconditionally on every healthy device. Instead, deploy it as an Intune Proactive Remediation. The included Detection Script tests whether Defender is already running and compliant. If the device is healthy, the remediation script never runs. It only intervenes on the machines that are actually broken.
What the Script Actually Does
This remediation script handles both layers of the Defender update stack in a single execution:
Step
Component Updated
Mechanism
Step 1
Security Intelligence + Engine
Update-MpSignature with fallback chain (Microsoft Update → MMPC)
Step 2
Defender Platform (KB4052623)
Windows Update COM API targeting Microsoft Update directly (bypasses WSUS)
Step 3
Verification
Polls Get-MpComputerStatus until versions change, then runs a final WU search
Before and After: What a Broken Defender Looks Like
When Defender platform updates are missing or the antimalware engine has been corrupted, Get-MpComputerStatus shows a clear picture of the damage:
Before: Defender Engine Not Running
Before remediation: AMEngineVersion 0.0.0.0, AMRunningMode Not running, AMServiceEnabled False.
Notice AMEngineVersion: 0.0.0.0 and AMRunningMode: Not running. The antimalware service is dead. The device has zero protection.
After: Defender Fully Updated and Running
After remediation: AMEngineVersion 1.1.26080.3, AMRunningMode Normal, all services enabled.
After running the remediation script: engine version is current, running mode is Normal, signatures are updated, and the antimalware service is active.
The Production Script: Complete PowerShell Code
Below is the full hardened remediation script. It was built for deployment via Intune Proactive Remediations, SCCM Task Sequences, or a Scheduled Task running as SYSTEM.
Important: This script must run as Administrator (SYSTEM context in Intune). It explicitly registers the Microsoft Update service to bypass WSUS. If your organization requires all updates to flow through WSUS, remove the AddService2 block in Step 2.
POWERSHELL • DefenderRemediation_v2.ps1
# ============================================================# TechEUC - Defender Update Remediation (v2 — Hardened)## Purpose:# Automatically install available Microsoft Defender updates# (Security Intelligence + Platform) from Microsoft Update.## This script does NOT contain a hard-coded Defender version.## Changes from v1:# - EULA acceptance before download# - Explicit Microsoft Update targeting (bypasses WSUS)# - Admin privilege enforcement# - Signature fallback chain (MU -> MMPC)# - Single-instance mutex# - WU service state preservation# - Polling loop instead of hardcoded sleep# - Log rotation (max 500 KB)# - UTF-8 log encoding# - COM object cleanup# - Network pre-check# - Defender-absent early exit## Log:# C:\ProgramData\TechEUC\DefenderUpdate\# DefenderRemediation.log# ============================================================#Requires -Version 5.1#Requires -RunAsAdministrator# ============================================================# CONFIGURATION# ============================================================$LogDir = "$env:ProgramData\TechEUC\DefenderUpdate"$LogFile = "$LogDir\DefenderRemediation.log"$LogMaxBytes = 512KB # rotate when log exceeds this$MutexName = "Global\TechEUCDefenderRemediation"$PollTimeout = 90 # max seconds to wait for Defender init$PollInterval = 10 # seconds between polls# Microsoft Update Service ID (constant, never changes)$MicrosoftUpdateServiceID = "7971f918-a847-4430-9279-4a52d1efe18d"# Exit codes$EXIT_SUCCESS = 0
$EXIT_DEFENDER_ABSENT = 10
$EXIT_NO_NETWORK = 11
$EXIT_ANOTHER_INSTANCE = 12
$EXIT_REMEDIATION_INCOMPLETE = 1
$EXIT_POST_CHECK_FAILED = 2
# ============================================================# BOOTSTRAP — directory, log rotation# ============================================================New-Item-Path$LogDir-ItemType Directory -Force | Out-Null# Log rotation: if the log exceeds $LogMaxBytes, keep the last halfif (Test-Path$LogFile) {
$LogInfo = Get-Item$LogFileif ($LogInfo.Length-gt$LogMaxBytes) {
$Lines = Get-Content$LogFile-Encoding UTF8
$HalfIdx = [math]::Floor($Lines.Count / 2)
$Lines[$HalfIdx..($Lines.Count - 1)] |
Set-Content$LogFile-Encoding UTF8 -Force
}
}
# ============================================================# FUNCTIONS# ============================================================functionWrite-Log {
param(
[string]$Message,
[string]$Level = "INFO"
)
$Time = Get-Date-Format"yyyy-MM-dd HH:mm:ss"$Line = "$Time [$Level] $Message"Write-Host$LineAdd-Content-Path$LogFile-Value$Line-Encoding UTF8
}
functionGet-DefenderStatus {
try {
$Status = Get-MpComputerStatus-ErrorAction Stop
return[PSCustomObject]@{
EngineVersion = $Status.AMEngineVersion
PlatformVersion = $Status.AMProductVersion
ServiceVersion = $Status.AMServiceVersion
AntivirusSignature = $Status.AntivirusSignatureVersion
RealTimeEnabled = $Status.RealTimeProtectionEnabled
}
}
catch {
Write-Log"Unable to retrieve Defender status: $($_.Exception.Message)""ERROR"return$null
}
}
functionRelease-ComObject {
param([object]$ComObject)
if ($null-ne$ComObject) {
try {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($ComObject)
}
catch {
# Swallow — object may already be collected
}
}
}
functionTest-InternetConnectivity {
# Quick DNS check against Microsoft endpoints$Targets = @(
"go.microsoft.com""definitionupdates.microsoft.com"
)
foreach ($Targetin$Targets) {
try {
$null = [System.Net.Dns]::GetHostAddresses($Target)
return$true
}
catch {
# try next
}
}
return$false
}
# ============================================================# RUNTIME ADMIN CHECK (belt-and-suspenders with #Requires)# ============================================================$CurrentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$CurrentPrincipal = [Security.Principal.WindowsPrincipal]$CurrentIdentityif (-not$CurrentPrincipal.IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Log"Script must run as Administrator. Exiting.""ERROR"exit$EXIT_REMEDIATION_INCOMPLETE
}
# ============================================================# SINGLE-INSTANCE MUTEX# ============================================================$Mutex = $nulltry {
$Mutex = [System.Threading.Mutex]::new($false, $MutexName)
if (-not$Mutex.WaitOne(0)) {
Write-Log"Another instance of TechEUC Defender Remediation is already running. Exiting.""WARNING"exit$EXIT_ANOTHER_INSTANCE
}
}
catch {
Write-Log"Mutex check failed (non-fatal): $($_.Exception.Message)""WARNING" # Continue — better to risk overlap than to skip remediation
}
# ============================================================# COM objects — declared at script scope so STEP 4 can use them# ============================================================$Session = $null$Searcher = $null$ServiceManager = $null$Downloader = $null$Installer = $null$Collection = $nulltry {
# ============================================================# START# ============================================================Write-Log"============================================================"Write-Log"TechEUC Defender Remediation v2 Started"Write-Log"Computer : $env:COMPUTERNAME"Write-Log"User : $env:USERNAME"Write-Log"============================================================"# ============================================================# PRE-FLIGHT: Network check# ============================================================if (-not (Test-InternetConnectivity)) {
Write-Log"No network connectivity to Microsoft endpoints. Exiting.""ERROR"exit$EXIT_NO_NETWORK
}
Write-Log"Network connectivity confirmed."# ============================================================# PRE-FLIGHT: Defender present?# ============================================================$Before = Get-DefenderStatusif ($null-eq$Before) {
Write-Log"Defender is not available on this machine (disabled, removed, or replaced by third-party AV).""ERROR"Write-Log"Exiting — nothing to remediate."exit$EXIT_DEFENDER_ABSENT
}
Write-Log"BEFORE UPDATE"Write-Log"Engine : $($Before.EngineVersion)"Write-Log"Platform : $($Before.PlatformVersion)"Write-Log"Service : $($Before.ServiceVersion)"Write-Log"AV Sig : $($Before.AntivirusSignature)"Write-Log"RTP : $($Before.RealTimeEnabled)"# ============================================================# STEP 1 — Defender Security Intelligence (Signatures)## Fallback chain: MicrosoftUpdateServer -> MMPC# ============================================================Write-Log"Starting Defender signature update (Security Intelligence)."$SigUpdated = $falsetry {
Update-MpSignature `
-UpdateSource MicrosoftUpdateServer `
-ErrorAction Stop
Write-Log"Signature update from Microsoft Update succeeded.""SUCCESS"$SigUpdated = $true
}
catch {
Write-Log"Microsoft Update source failed: $($_.Exception.Message)""WARNING"Write-Log"Attempting MMPC fallback..."try {
Update-MpSignature `
-UpdateSource MMPC `
-ErrorAction Stop
Write-Log"Signature update from MMPC succeeded.""SUCCESS"$SigUpdated = $true
}
catch {
Write-Log"MMPC fallback also failed: $($_.Exception.Message)""WARNING"Write-Log"Signature update could not be completed from any source.""WARNING"
}
}
# ============================================================# STEP 2 — Defender Platform Update via Windows Update COM API## Explicitly targets Microsoft Update (not WSUS).# ============================================================Write-Log"Checking Microsoft Update for Defender Platform updates."# --------------------------------------------------------# Preserve and start WU service# --------------------------------------------------------$OriginalWUStartType = $nulltry {
$WUSvc = Get-Service-Name wuauserv -ErrorAction Stop
$OriginalWUStartType = $WUSvc.StartTypeif ($WUSvc.StartType-eq 'Disabled') {Set-Service-Name wuauserv -StartupType Manual -ErrorAction Stop
Write-Log"Changed wuauserv startup from Disabled to Manual (will restore)."
}
if ($WUSvc.Status-ne 'Running') {Start-Service-Name wuauserv -ErrorAction Stop
Write-Log"Started wuauserv service."
}
}
catch {
Write-Log"Could not ensure wuauserv is running: $($_.Exception.Message)""WARNING"
}
# --------------------------------------------------------# Create COM objects and register Microsoft Update# --------------------------------------------------------$Session = New-Object-ComObject Microsoft.Update.Session
$Session.ClientApplicationID = "TechEUC Defender Remediation"# Register Microsoft Update service so we bypass WSUS$ServiceManager = New-Object-ComObject Microsoft.Update.ServiceManager
$ServiceManager.ClientApplicationID = "TechEUC Defender Remediation"$RegisteredService = $nulltry {
# AddService2 flags: 7 = asfAllowPendingRegistration | # asfAllowOnlineRegistration | # asfRegisterServiceWithAU$RegisteredService = $ServiceManager.AddService2(
$MicrosoftUpdateServiceID, 7, ""
)
Write-Log"Microsoft Update service registered for this session."
}
catch {
Write-Log"Could not register Microsoft Update service: $($_.Exception.Message)""WARNING"Write-Log"Falling back to default update source (may be WSUS)."
}
$Searcher = $Session.CreateUpdateSearcher()
# Point the searcher at Microsoft Update (not WSUS)if ($null-ne$RegisteredService) {
$Searcher.ServerSelection = 3 # ssOthers$Searcher.ServiceID = $RegisteredService.ServiceID
}
Write-Log"Searching Microsoft Update for pending Defender updates..."try {
$SearchResult = $Searcher.Search(
"IsInstalled=0 and IsHidden=0 and Type='Software'"
)
}
catch {
Write-Log"Update search failed: $($_.Exception.Message)""ERROR"$SearchResult = $null
}
if ($null-ne$SearchResult-and$SearchResult.Updates.Count-gt 0) {
# -------------------------------------------------------- # Filter to Defender updates only # --------------------------------------------------------$DefenderUpdates = @(
$SearchResult.Updates | Where-Object {
$_.Title-match"Microsoft Defender Antivirus"-or$_.Title-match"Windows Defender Antivirus"-or$_.Title-match"KB4052623"
}
)
if ($DefenderUpdates.Count-eq 0) {
Write-Log"No Defender Platform update is currently pending."
}
else {
Write-Log"Found $($DefenderUpdates.Count) Defender update(s)."foreach ($Updatein$DefenderUpdates) {
Write-Log"------------------------------------------------------------"Write-Log"Processing Defender update:"Write-Log" Title : $($Update.Title)"Write-Log" KB : $($Update.KBArticleIDs -join ', ')"Write-Log" UpdateID : $($Update.Identity.UpdateID)" # ------------------------------------------------ # Accept EULA (required before download) # ------------------------------------------------if (-not$Update.EulaAccepted) {
try {
$Update.AcceptEula()
Write-Log" EULA accepted."
}
catch {
Write-Log" EULA acceptance failed: $($_.Exception.Message)""ERROR"Write-Log" Skipping this update."continue
}
}
# ------------------------------------------------ # Create update collection # ------------------------------------------------$Collection = New-Object-ComObject Microsoft.Update.UpdateColl
[void]$Collection.Add($Update)
# ------------------------------------------------ # Download # ------------------------------------------------Write-Log" Downloading update..."$Downloader = $Session.CreateUpdateDownloader()
$Downloader.Updates = $Collectiontry {
$DownloadResult = $Downloader.Download()
}
catch {
Write-Log" Download threw an exception: $($_.Exception.Message)""ERROR"Release-ComObject$CollectionRelease-ComObject$Downloadercontinue
}
Write-Log" Download ResultCode: $($DownloadResult.ResultCode)" # ResultCode: 2 = Succeeded, 3 = SucceededWithErrorsif ($DownloadResult.ResultCode-notin @(2, 3)) {
Write-Log" Download failed (ResultCode $($DownloadResult.ResultCode)). Skipping install.""ERROR"Release-ComObject$CollectionRelease-ComObject$Downloadercontinue
}
# ------------------------------------------------ # Install # ------------------------------------------------Write-Log" Download completed. Installing update..."$Installer = $Session.CreateUpdateInstaller()
$Installer.Updates = $Collection # Suppress UI prompts (IUpdateInstaller2/3 — may not exist on all builds)try { $Installer.AllowSourcePrompts = $false } catch {}
try { $Installer.ForceQuiet = $true } catch {}
try {
$InstallResult = $Installer.Install()
}
catch {
Write-Log" Install threw an exception: $($_.Exception.Message)""ERROR"Release-ComObject$CollectionRelease-ComObject$DownloaderRelease-ComObject$Installercontinue
}
Write-Log" Install ResultCode : $($InstallResult.ResultCode)"Write-Log" Reboot Required : $($InstallResult.RebootRequired)"if ($InstallResult.ResultCode-eq 2) {
Write-Log" Defender update installed successfully.""SUCCESS"
}
elseif ($InstallResult.ResultCode-eq 3) {
Write-Log" Defender update installed with warnings.""WARNING"
}
else {
Write-Log" Defender update installation returned non-success (ResultCode $($InstallResult.ResultCode)).""WARNING"
}
Release-ComObject$CollectionRelease-ComObject$DownloaderRelease-ComObject$Installer
}
}
}
else {
Write-Log"No pending Defender updates found via Microsoft Update."
}
# ============================================================# STEP 3 — Wait for Defender to initialize (polling loop)# ============================================================Write-Log"Waiting for Defender components to initialize (max ${PollTimeout}s)..."$Elapsed = 0
while ($Elapsed-lt$PollTimeout) {
Start-Sleep-Seconds$PollInterval$Elapsed += $PollInterval$Check = Get-DefenderStatusif ($null-ne$Check) {
# If the platform version changed, Defender has re-initializedif ($Before.PlatformVersion-ne$Check.PlatformVersion-or$Before.EngineVersion-ne$Check.EngineVersion) {
Write-Log"Defender versions changed after ${Elapsed}s — initialization complete."break
}
}
}
if ($Elapsed-ge$PollTimeout) {
Write-Log"Timed out waiting for Defender re-initialization (${PollTimeout}s). Proceeding with verification.""WARNING"
}
# ============================================================# AFTER STATUS# ============================================================$After = Get-DefenderStatusif ($null-eq$After) {
Write-Log"Unable to verify Defender status after remediation.""ERROR"exit$EXIT_POST_CHECK_FAILED
}
Write-Log"AFTER UPDATE"Write-Log"Engine : $($After.EngineVersion)"Write-Log"Platform : $($After.PlatformVersion)"Write-Log"Service : $($After.ServiceVersion)"Write-Log"AV Sig : $($After.AntivirusSignature)"Write-Log"RTP : $($After.RealTimeEnabled)"# ============================================================# STEP 4 — Final check: any Defender updates still pending?# ============================================================Write-Log"Performing final Microsoft Update check for remaining Defender updates."if ($null-ne$Searcher) {
try {
$FinalSearch = $Searcher.Search(
"IsInstalled=0 and IsHidden=0 and Type='Software'"
)
$RemainingUpdates = @(
$FinalSearch.Updates | Where-Object {
$_.Title-match"Microsoft Defender Antivirus"-or$_.Title-match"Windows Defender Antivirus"-or$_.Title-match"KB4052623"
}
)
if ($RemainingUpdates.Count-gt 0) {
Write-Log"Defender update(s) are still pending after remediation.""WARNING"foreach ($Remainingin$RemainingUpdates) {
Write-Log" Pending: $($Remaining.Title)"
}
Write-Log"RESULT: REMEDIATION INCOMPLETE.""WARNING"exit$EXIT_REMEDIATION_INCOMPLETE
}
else {
Write-Log"No remaining Defender updates pending."
}
}
catch {
Write-Log"Final update check failed: $($_.Exception.Message)""ERROR"exit$EXIT_POST_CHECK_FAILED
}
}
else {
Write-Log"Searcher not available — skipping final Windows Update verification.""WARNING"
}
# ============================================================# FINAL RESULT# ============================================================Write-Log"============================================================"Write-Log"SUCCESS — Defender is up to date with available updates."Write-Log"Final Engine : $($After.EngineVersion)"Write-Log"Final Platform : $($After.PlatformVersion)"Write-Log"Final Service : $($After.ServiceVersion)"Write-Log"Final AV Sig : $($After.AntivirusSignature)"Write-Log"Log File : $LogFile"Write-Log"============================================================"Write-Host""Write-Host"============================================================"Write-Host" ***** DEFENDER REMEDIATION SUCCESS *****"Write-Host"============================================================"Write-Host" Engine : $($After.EngineVersion)"Write-Host" Platform : $($After.PlatformVersion)"Write-Host" Service : $($After.ServiceVersion)"Write-Host" Log File : $LogFile"Write-Host"============================================================"exit$EXIT_SUCCESS
} # end outer try# ============================================================# CLEANUP — always runs# ============================================================finally {
# -------------------------------------------------------- # Release COM objects # --------------------------------------------------------foreach ($Objin @($Installer, $Downloader, $Collection, $Searcher, $Session, $ServiceManager)) {
Release-ComObject$Obj
}
# -------------------------------------------------------- # Restore WU service startup type # --------------------------------------------------------if ($null-ne$OriginalWUStartType) {
try {
Set-Service-Name wuauserv -StartupType$OriginalWUStartType-ErrorAction SilentlyContinue
Write-Log"Restored wuauserv startup type to: $OriginalWUStartType"
}
catch {
# Best-effort
}
}
# -------------------------------------------------------- # Release mutex # --------------------------------------------------------if ($null-ne$Mutex) {
try {
$Mutex.ReleaseMutex()
$Mutex.Dispose()
}
catch {
# Best-effort
}
}
Write-Log"Cleanup complete. Script exiting."
}
How to Deploy via Intune Proactive Remediations
The fastest way to push this across your fleet is through Intune Proactive Remediations (now called Remediations under Devices).
Step 1: Create a Detection Script
The detection script checks whether the Defender engine is running and whether the platform version is current. If either check fails, it returns a non-zero exit code, which triggers the remediation.
POWERSHELL • DefenderDetection.ps1
# ============================================================# Detection Script - Check Defender Health# ============================================================try {
$Status = Get-MpComputerStatus-ErrorAction Stop
if ($Status.AMRunningMode-ne"Normal"-or$Status.AMEngineVersion-eq"0.0.0.0"-or$Status.AMServiceEnabled-eq$false) {
Write-Host"Defender is not healthy. Remediation required."exit 1
}
Write-Host"Defender is healthy. Engine: $($Status.AMEngineVersion)"exit 0
}
catch {
Write-Host"Cannot query Defender: $($_.Exception.Message)"exit 1
}
Step 2: Upload Both Scripts to Intune
Go to Devices → Remediations → + Create script package.
Name it TechEUC - Defender Update Remediation.
Upload the detection script and the remediation script (the full script above).
Set Run this script using the logged-on credentials to No (runs as SYSTEM).
Set Run script in 64-bit PowerShell to Yes.
Assign to your target device groups.
Set the schedule (recommended: every 4 hours for the first week, then daily).
Exit Codes Reference
The script uses distinct exit codes so you can filter results in Intune reporting or your SIEM:
Exit Code
Meaning
Action Required
0
Success — Defender is up to date
None
1
Remediation incomplete — updates still pending
Check network, WSUS approval, or re-run
2
Post-check failed — cannot verify final state
Check Defender service health
10
Defender absent or disabled on this machine
Check if third-party AV is installed
11
No network connectivity to Microsoft endpoints
Check firewall rules and proxy settings
12
Another script instance already running
Wait for existing instance to finish
Key Hardening Features in This Script
If you have used simpler Defender update scripts before, you will notice this one handles a number of edge cases that break production deployments:
EULA acceptance: The Windows Update COM API requires programmatic EULA acceptance before downloading. Without it, downloads fail silently.
Microsoft Update bypass: On WSUS-managed devices, the default WUA searcher talks to WSUS, not Microsoft Update. This script explicitly registers the Microsoft Update service (ServiceID 7971f918-a847-4430-9279-4a52d1efe18d) so it always finds the latest Defender platform version.
Signature fallback chain: If MicrosoftUpdateServer fails (common behind corporate proxies), the script falls back to MMPC (Microsoft Malware Protection Center).
Single-instance mutex: Prevents two copies from running simultaneously when both Intune Remediations and a Scheduled Task trigger at the same time.
WU service state preservation: Captures the original wuauserv startup type before changing it, and restores it in the finally block.
COM object cleanup: All WUA COM objects are released via Marshal::ReleaseComObject() in the finally block to prevent handle leaks.
Polling loop instead of hardcoded sleep: Instead of Start-Sleep -Seconds 45, the script polls Get-MpComputerStatus every 10 seconds for up to 90 seconds, breaking early when versions change.
Frequently Asked Questions
Does this script require internet access?
Yes. The script contacts Microsoft Update servers directly. If your devices sit behind a proxy that blocks *.microsoft.com, both the signature update and the platform update will fail. The script does a DNS pre-check and exits with code 11 if connectivity is not available.
Will this script conflict with WSUS or SCCM update management?
The script registers the Microsoft Update service for the current session only. It does not permanently change the device’s WSUS configuration or Group Policy settings. After the script exits, the device continues using its configured update source for all other updates.
Can I use this script with Intune’s native Windows Update policies?
Yes. This script complements Intune Update Rings. The Update Ring controls the normal update cadence. This script acts as an emergency remediation for devices where the normal cadence has failed or where Defender is broken and needs immediate recovery.
Does the script trigger a reboot?
No. The script never calls Restart-Computer. It logs whether a reboot is required but leaves the decision to your existing reboot policy (Intune Update Ring deadline, GPO, or manual action).
Conclusion
When Defender falls behind on platform updates, a simple Update-MpSignature is not enough. KB4052623 ships through Windows Update, and on WSUS-managed devices it can stay unapproved indefinitely. This script bridges that gap by talking directly to Microsoft Update, handling EULA acceptance, cleaning up COM objects, and reporting distinct exit codes for every failure mode.
Deploy it as an Intune Remediation, let it run on a 4-hour schedule, and your Defender compliance numbers will stop bleeding red.
Need help building custom Intune remediation scripts for your organization?
Senior Microsoft 365, EUC & Cloud Endpoint Architect
Need custom Win32 App Packaging, PowerShell Automation, Zero-Touch Intune Autopilot, or SCCM Co-Management for your enterprise or MSP? I specialize in production-grade deployment architectures with zero downtime.
Force Update Microsoft Defender Antivirus Platform Using PowerShell [Intune Remediation Script]
Table of content
Why Defender Falls Behind and Why
Update-MpSignatureAlone Is Not EnoughYou open the Intune compliance dashboard and see it: “Update Microsoft Defender to version 1.1.26080.3” flagged as a zero-day security update. The device shows non-compliant. Your instinct is to run
Update-MpSignatureand move on.Here is the problem.
Update-MpSignatureonly updates security intelligence (definitions) and the engine. It does not touch the Defender platform (theAMProductVersionvalue you see underGet-MpComputerStatus). The platform update ships as a separate Windows Update package under KB4052623, and it requires the Windows Update Agent COM API to install.On WSUS-managed or SCCM co-managed devices, the situation gets worse. If the WSUS admin has not approved KB4052623, the device will never receive the platform update through standard channels. The device stays non-compliant indefinitely.
How Microsoft Defender Updates Work Normally (Without Scripts)
In a healthy enterprise environment, you should not need a script to update Defender on every machine. Microsoft Defender Antivirus is engineered to maintain itself autonomously across three distinct update layers:
(Signatures)
(KB4052623)
MsMpEng.exe), drivers, and network inspectionEnterprise administrators typically control this behavior natively through Microsoft Intune and policy baselines using two primary methods:
1. Intune Defender Update Controls (Endpoint Security)
Under Endpoint security > Antivirus > Microsoft Defender Antivirus policy, Microsoft provides dedicated Defender Update Controls. These allow you to assign release channels for each component without writing code:
2. Windows Update for Business (WUfB) Update Rings
Because the core platform (KB4052623) is distributed as a Windows Update package, healthy cloud-managed endpoints receive it automatically during their normal Windows Update check cycle, adhering to quality update deferral and maintenance windows.
When Do You Actually Need a PowerShell Remediation Script?
If Microsoft designed Defender to update itself, why does this script exist? Because in large enterprise fleets, 5% to 10% of devices inevitably fall out of the standard pipeline. When that happens, compliance fails, zero-day vulnerabilities remain exposed, and standard portal buttons cannot force the update.
Here is a breakdown of when native automation works versus when this remediation script is required:
AMEngineVersionshows0.0.0.0and protection is “Not Running”.wuauservto Disabled.wuauservto Manual, runs update, and restores original state.What the Script Actually Does
This remediation script handles both layers of the Defender update stack in a single execution:
Update-MpSignaturewith fallback chain (Microsoft Update → MMPC)Get-MpComputerStatusuntil versions change, then runs a final WU searchBefore and After: What a Broken Defender Looks Like
When Defender platform updates are missing or the antimalware engine has been corrupted,
Get-MpComputerStatusshows a clear picture of the damage:Before: Defender Engine Not Running
Notice
AMEngineVersion: 0.0.0.0andAMRunningMode: Not running. The antimalware service is dead. The device has zero protection.After: Defender Fully Updated and Running
After running the remediation script: engine version is current, running mode is Normal, signatures are updated, and the antimalware service is active.
The Production Script: Complete PowerShell Code
Below is the full hardened remediation script. It was built for deployment via Intune Proactive Remediations, SCCM Task Sequences, or a Scheduled Task running as SYSTEM.
AddService2block in Step 2.POWERSHELL • DefenderRemediation_v2.ps1
How to Deploy via Intune Proactive Remediations
The fastest way to push this across your fleet is through Intune Proactive Remediations (now called Remediations under Devices).
Step 1: Create a Detection Script
The detection script checks whether the Defender engine is running and whether the platform version is current. If either check fails, it returns a non-zero exit code, which triggers the remediation.
POWERSHELL • DefenderDetection.ps1
Step 2: Upload Both Scripts to Intune
TechEUC - Defender Update Remediation.Exit Codes Reference
The script uses distinct exit codes so you can filter results in Intune reporting or your SIEM:
012101112Key Hardening Features in This Script
If you have used simpler Defender update scripts before, you will notice this one handles a number of edge cases that break production deployments:
7971f918-a847-4430-9279-4a52d1efe18d) so it always finds the latest Defender platform version.MicrosoftUpdateServerfails (common behind corporate proxies), the script falls back toMMPC(Microsoft Malware Protection Center).wuauservstartup type before changing it, and restores it in thefinallyblock.Marshal::ReleaseComObject()in thefinallyblock to prevent handle leaks.Start-Sleep -Seconds 45, the script pollsGet-MpComputerStatusevery 10 seconds for up to 90 seconds, breaking early when versions change.Frequently Asked Questions
Does this script require internet access?
Yes. The script contacts Microsoft Update servers directly. If your devices sit behind a proxy that blocks
*.microsoft.com, both the signature update and the platform update will fail. The script does a DNS pre-check and exits with code11if connectivity is not available.Will this script conflict with WSUS or SCCM update management?
The script registers the Microsoft Update service for the current session only. It does not permanently change the device’s WSUS configuration or Group Policy settings. After the script exits, the device continues using its configured update source for all other updates.
Can I use this script with Intune’s native Windows Update policies?
Yes. This script complements Intune Update Rings. The Update Ring controls the normal update cadence. This script acts as an emergency remediation for devices where the normal cadence has failed or where Defender is broken and needs immediate recovery.
Does the script trigger a reboot?
No. The script never calls
Restart-Computer. It logs whether a reboot is required but leaves the decision to your existing reboot policy (Intune Update Ring deadline, GPO, or manual action).Conclusion
When Defender falls behind on platform updates, a simple
Update-MpSignatureis not enough. KB4052623 ships through Windows Update, and on WSUS-managed devices it can stay unapproved indefinitely. This script bridges that gap by talking directly to Microsoft Update, handling EULA acceptance, cleaning up COM objects, and reporting distinct exit codes for every failure mode.Deploy it as an Intune Remediation, let it run on a 4-hour schedule, and your Defender compliance numbers will stop bleeding red.
Need help building custom Intune remediation scripts for your organization?
👉 Hire me on Fiverr Pro | 📧 Contact TechEUC
Atoofa Shaikh
Senior Microsoft 365, EUC & Cloud Endpoint Architect
Need custom Win32 App Packaging, PowerShell Automation, Zero-Touch Intune Autopilot, or SCCM Co-Management for your enterprise or MSP? I specialize in production-grade deployment architectures with zero downtime.
Table of content
Subscribe to Blog
Signup to our weekly newsletter
category
Connect with Us
Recommended Posts
Force Update Microsoft Defender Antivirus Platform Using PowerShell [Intune Remediation Script]
How to Collect Windows Registry Data Using Intune (Properties Catalog)
Deploy Win32 Apps Using Native PowerShell Script Installer in Intune [Complete Guide]