Force Windows Update on Intune Managed Windows 11 Devices
A common and frustrating challenge for Intune administrators: your policies are set, but devices remain out-of-date because the local Windows Update Service is stuck or corrupted. These Intune devices not updating pose a significant security risk, forcing IT staff into manual troubleshooting
INTUNEM365
11/21/20259 min read


Introduction - Solving the Intune Update Compliance Gap
Are you constantly battling devices that refuse to install the latest security patches, leaving you with lapsed Windows 11 compliance?
This is a common and frustrating challenge for Intune administrators: your policies are set, but devices remain out-of-date because the local Windows Update Service is stuck or corrupted. These Intune devices not updating pose a significant security risk, forcing IT staff into manual troubleshooting.
The Solution: Intune Proactive Remediations
The solution lies in leveraging Intune Proactive Remediations —now simply called Remediations—to automatically detect, reset, and force the update process without manual intervention.
In this guide, we provide a robust detection and remediation script package designed to target devices pending a reboot or stuck in a non-compliant state
Our script package will safely and effectively:
Detect a pending update or required reboot using multiple, comprehensive registry checks
Force the installation using the modern usoclient ScanInstallWait command
Schedule a graceful reboot with a 30-minute user notification to ensure data is saved
Follow this step-by-step guide to implement this crucial PowerShell script solution and regain control over your fleet's update status
Solution Overview: How the Proactive Remediation Package Works
This solution uses a pair of PowerShell scripts—a Detection Script and a Remediation Script—deployed via Intune Proactive Remediations. The goal is to enforce security updates and complete necessary reboots on non-compliant devices.
The Mechanism
Detection (Detect.ps1): The script runs and checks for multiple indicators of an incomplete update or pending reboot. If any key is found (like the Windows Update RebootRequired key or PendingFileRenameOperations), the script returns an Exit Code 1 (Non-Compliant), which triggers the remediation
Remediation (Remediation.ps1): This script executes only if the device is detected as non-compliant. It first attempts to ensure the Windows Update Service (wuauserv) is running. It then uses the usoclient ScanInstallWait command to initiate a combined scan, download, and installation of updates. Finally, it initiates a graceful 30-minute reboot if the updates require it
The scripts are designed to automatically detect and fix devices that are pending a reboot after updates.
Deep Dive: The Detection Script (Detect.ps1)
The detection script is the gatekeeper of this solution. Its sole job is to determine if a device requires an action (a forced update/reboot) and signal this by exiting with a non-zero code.
The Detection Logic: Exit Code 1
For Proactive Remediations, an Exit Code 1 (or any non-zero value) returned by the detection script means the device is Non-Compliant, triggering the remediation script. An Exit Code 0 means the device is Compliant, and no action is taken.
Our script employs a comprehensive check across three critical registry locations, ensuring that we catch pending actions from various system components and installers, not just the Windows Update service:
Windows Update Required Key ($WURebootRequired):
Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired
Purpose: This is the general indicator set by the Windows Update process itself
Component-Based Servicing ($CBSRebootPending):
Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
Purpose: This specifically indicates a required reboot tied to the Servicing Stack or a Cumulative Update installation
Pending File Rename Operations ($PFROPending):
Path: HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
Purpose: This is the most robust check. Various installers (Microsoft Office, third-party software, Windows components) use this location to queue files that must be replaced after the next reboot. Its existence is a strong, universal indicator that a restart is needed to complete file operations
If any of these three checks return $true, the Test-PendingReboot function returns $true, and the script exits with Exit Code 1, triggering the powerful remediation script
The Detection Script (Detect.ps1) Content
PowerShell
# Detection Script: Check for All Pending Reboot Flags
# Exit 1 = Non-Compliant (Remediation will run)
# Exit 0 = Compliant (No remediation needed)
$global:ExitCode = 0
function Test-PendingReboot {
# 1. Windows Update - Auto Update RebootRequired Key
$WURebootRequired = Test-Path -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
# 2. Component-Based Servicing (CBS) - For servicing stack/cumulative updates
$CBSRebootPending = Test-Path -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
# 3. Session Manager - Pending File Rename Operations (a strong indicator from various installers)
$PFRORegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
try {
# Check if the PendingFileRenameOperations value exists AND is not empty
$PFRO = (Get-ItemProperty -Path $PFRORegistryPath -Name 'PendingFileRenameOperations' -ErrorAction Stop).PendingFileRenameOperations
if ($PFRO -ne $null -and $PFRO.Length -gt 0) {
$PFROPending = $true
} else {
$PFROPending = $false
}
} catch {
# If the key/value doesn't exist, Get-ItemProperty will throw an error, which is fine (not pending).
$PFROPending = $false
}
# Report the highest priority issue found
if ($WURebootRequired -or $CBSRebootPending -or $PFROPending) {
Write-Host "Detection: Pending reboot detected. WUKey: $WURebootRequired, CBSKey: $CBSRebootPending, PFRO: $PFROPending. Remediation is required."
return $true
}
Write-Host "Detection: No critical pending reboot detected."
return $false
}
if (Test-PendingReboot) {
$global:ExitCode = 1
}
exit $global:ExitCode
Deep Dive: The Remediation Script (Remediation.ps1)
The Remediation Script is responsible for taking corrective action, but it is engineered with several best practices to ensure minimal disruption while guaranteeing the required updates are installed.
Key Steps and Safety Features
The script executes three primary functions: logging, forcing the update, and ensuring a graceful reboot.
Robust Logging (For Troubleshooting) The script establishes logging to three destinations, which is excellent for audit and troubleshooting:
A local log file ($env:TEMP\Intune_Remediation_Force_Update.log).
The Windows Event Log (Application Log) using a custom source (Intune-ProactiveRemediation-WU).
The PowerShell host, which is reported back to the Intune console.
Forcing the Update Process The script first confirms the Windows Update Service (wuauserv) is running. The core of the action is the command: usoclient ScanInstallWait This is the modern, recommended method to tell the Update Orchestrator Service (USOClient) to perform a combined scan, download, and install cycle in a single operation.
Post-Install Compliance Check and Wait After the USOClient process completes, the script enters a wait loop (up to 10 minutes). It continuously checks if the $RebootRequiredPath key has been removed. This loop is critical because it confirms the installation phase is truly finished before deciding whether a reboot is necessary.
Graceful Reboot and User Notification (The Crucial Safety Measure) If the reboot key is still present after the wait loop, a critical update is assumed to be pending, and the script prioritizes user safety.
Immediate Message: It first sends an immediate, persistent console message using the msg * command. This provides immediate visibility to the user.
Delayed Reboot: It then schedules a graceful shutdown using shutdown /r /t 1800 (1800 seconds = 30 minutes). This provides the end-user with a countdown and a mandatory window to save their work, preventing sudden data loss.
Compliance Flag Finally, the script sets a custom registry flag (HKLM:\Software\Company\Compliance\UpdateRemediated). This flag is an excellent method for using dynamic groups or custom compliance policies in the future to confirm when a device was last remediated.
The Remediation Script (Remediation.ps1) Content
# Remediation Script: Force Windows Update Scan, Install, and Graceful Reboot
# --- Logging Setup ---
$LogPath = "$env:TEMP\Intune_Remediation_Force_Update.log"
$EventSource = "Intune-ProactiveRemediation-WU"
# Ensure the custom event source exists (needed for security log entry, runs only once)
if (-not ([System.Diagnostics.EventLog]::SourceExists($EventSource))) {
New-EventLog -LogName Application -Source $EventSource -ErrorAction SilentlyContinue | Out-Null
}
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogLine = "[$Timestamp] [$Level] $Message"
# 1. Write to the local log file
Add-Content -Path $LogPath -Value $LogLine
# 2. Write to the Windows Event Log (Application Log)
$EntryType = "Information"
$EventID = 1000 # Use a specific ID for filtering
switch ($Level) {
"WARN" { $EntryType = "Warning"; $EventID = 2001 }
"ERROR" { $EntryType = "Error"; $EventID = 3001 }
"CRITICAL" { $EntryType = "Error"; $EventID = 4001 }
}
try {
Write-EventLog -LogName Application -Source $EventSource -EntryType $EntryType -EventId $EventID -Message $LogLine
} catch {
# Catch errors if writing to the log fails, but don't stop the main script execution
Write-Host "WARNING: Failed to write to the Windows Event Log. $($_.Exception.Message)"
}
# 3. Write to the PowerShell host for Intune reporting
Write-Host $LogLine
}
Write-Log "--- Starting Windows Update Remediation Script ---"
# --- Variables ---
$RebootRequiredPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
$MaxWaitMinutes = 10
$WaitIntervalSeconds = 60
# --- Start Windows Update Service (Same as before) ---
Write-Log "Attempting to ensure Windows Update Service (wuauserv) is running..."
# ... (rest of service check code) ...
try {
Set-Service -Name wuauserv -StartupType Automatic -ErrorAction Stop
Start-Service -Name wuauserv -ErrorAction Stop
Write-Log "Service ensured to be running."
} catch {
Write-Log "WARN: Service start failed or was already running. Error: $($_.Exception.Message)" "WARN"
}
# --- Trigger USOClient Scan and Install (Same as before) ---
Write-Log "Triggering combined scan, download, and install (ScanInstallWait)..."
# ... (rest of USOClient code) ...
try {
$Process = Start-Process -FilePath "usoclient" -ArgumentList "ScanInstallWait" -Wait -PassThru -ErrorAction Stop
Write-Log "USOClient ScanInstallWait initiated and completed its foreground process. Exit Code: $($Process.ExitCode)"
} catch {
Write-Log "ERROR: Failed to run USOClient ScanInstallWait. Update may be blocked." "ERROR"
}
# --- Post-Install Compliance Check and Wait (Same as before) ---
Write-Log "Checking for pending reboot keys after update trigger. Waiting up to $MaxWaitMinutes minutes..."
$RebootStillPending = $true
$Attempts = 0
do {
$Attempts++
$RebootStillPending = Test-Path -Path $RebootRequiredPath
if (-not $RebootStillPending) {
Write-Log "SUCCESS: RebootRequired key removed after $Attempts attempts. Update process appears complete."
break
}
if ($Attempts -lt ($MaxWaitMinutes * 60 / $WaitIntervalSeconds)) {
Write-Log "RebootRequired key still present (Attempt $Attempts). Waiting $WaitIntervalSeconds seconds..."
Start-Sleep -Seconds $WaitIntervalSeconds
}
} while ($RebootStillPending -and ($Attempts -lt ($MaxWaitMinutes * 60 / $WaitIntervalSeconds)))
# --- Final Action: Reboot if required, or exit gracefully (with enhanced user notification) ---
if ($RebootStillPending -eq $true) {
# 1. Send an immediate, persistent console message to the user
Write-Log "Sending immediate console message to user." "CRITICAL"
try {
cmd /c "msg * /TIME:300 'CRITICAL UPDATE: Mandatory updates have been installed. Your device will restart in 30 minutes to complete the process. Please save all work now!'"
} catch {
Write-Log "WARN: Failed to send user message using MSG command. Error: $($_.Exception.Message)" "WARN"
}
# 2. Schedule the graceful 30-minute reboot (1800 seconds)
$RebootDelaySeconds = 1800
$RebootMessage = "CRITICAL UPDATE: Your device will restart in 30 minutes to complete mandatory updates. Please save your work now."
Write-Log "Reboot is required. Initiating graceful shutdown /r /t $RebootDelaySeconds. The user will see a countdown." "CRITICAL"
cmd /c "shutdown /r /t $RebootDelaySeconds /c '$RebootMessage'"
} else {
Write-Log "No reboot is required based on the registry check. Exiting successfully."
}
# --- Compliance Flag (Same as before) ---
# ... (rest of compliance flag code) ...
try {
New-Item -Path "HKLM:\Software\Company" -Name "Compliance" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\Software\Company\Compliance" -Name "UpdateRemediated" -Value "$(Get-Date -Format 'yyyyMMdd')"
Write-Log "Compliance flag set in registry."
} catch {
Write-Log "WARN: Failed to set compliance flag." "WARN"
Implementation Guide: Prerequisites and Group Setup
Before deploying the script package, you must ensure your tenant meets the necessary licensing requirements for Proactive Remediations and create the target device group.
Licensing Attestation (Critical Requirement)
Using Proactive Remediations requires a Windows Enterprise or equivalent license (e.g., Windows Enterprise E3 or E5) for the end-users on the target devices.
You must confirm ownership of these licenses in the Intune Admin Center:
Go to Tenant administration > Connectors and tokens > Windows data.
Set the Windows license verification toggle to On.
Click Save.
This action attests to your organisation owning the necessary licenses and enables the Remediations feature in your tenant
Create the Target Device Group
You need a device group to target the script package. This group can be populated manually (Assigned) or dynamically (Dynamic Device) based on criteria like OS version or time since last check-in.
In the Microsoft Intune admin center, navigate to Groups > New Group
Set the Group type to Security
Give the group a clear name, such as 'Out of Date Windows 11 devices'
Set the Membership type to Assigned (for manual addition) or Dynamic Device (for rule-based membership). For a proof of concept, Assigned may be simplest
Click Create to save the group
Prepare the Scripts
Ensure your two PowerShell files are ready for upload:
Detect.ps1: Contains the logic to check for the three pending reboot registry keys
Remediation.ps1: Contains the logic to run usoclient ScanInstallWait and initiate the graceful 30-minute reboot
Step-by-Step Script Deployment in Microsoft Intune
With your groups created and your scripts (Detect.ps1 and Remediation.ps1) ready, you can now upload and configure the solution in Intune.
Create the Custom Script Package
Navigate to Devices > Scripts and remediations in the Intune Admin Center
Under the Remediations tab, click Create
On the Basics tab, complete the required information:
Name: Force Windows Updates
Description: (Enter a description)
Publisher: (Your name or Company name, e.g., Kumonix)
Version: 1
Configure Script Settings
This step is crucial for ensuring the scripts run correctly in the system context and with the correct environment
Move to the Settings tab
Detection script file: Upload the Detect.ps1 file7. The preview window will display its contents for confirmation
Remediation script file: Upload the Remediation.ps1 file. The preview will show its contents
Configure the three bottom options exactly as follows:
Run this script using the logged-on credentials: No (Scripts must run as the System account to manage services and registry keys (like HKLM))
Enforce script signature check: No (Unless you have signed your PowerShell scripts with a trusted certificate)
Run script in 64-bit PowerShell: Yes (Recommended for all modern Windows system scripts to ensure compatibility)
Assign the Package and Schedule
Click Next and apply any Scope tags you wish to use
Click Next again to reach the Assignments tab
Under Included groups, locate and select the target group you previously created (e.g., 'Out of Date Windows 11 devices')
Choose the desired Schedule (e.g., Daily is a good starting point for compliance fixes)
Click Next and review all settings on the Review + create tab
Click Create to finish the process
The script will now begin checking your target devices according to the defined schedule
Results and Validation: Monitoring Success
Once your script package has been deployed, the final step is monitoring the results to confirm your solution is successfully enforcing compliance across the target devices.
Navigate to Devices > Scripts and remediations in the Intune Admin Center.
Select your script package (Force Windows Updates).
Review the Overview dashboard.
This Force Windows Update Intune Script package provides a robust, self-healing mechanism for a critical compliance issue.
If you are looking for further efficiencies, you could refine the targeting group by creating a Dynamic Device Group rule that leverages the UpdateRemediated custom registry flag set by the remediation script. This allows you to specifically target only those devices that have not been successfully remediated in the last 30 or 60 days, focusing your script's efforts where they are truly needed
Microsoft Solutions Provider
Kumonix are a Microsoft Solutions provider helping organisations transform and improve with cloud-based engagements.
© 2026. All rights reserved.
Modern Endpoint Management
Microsoft AI & Automation
Modern Workplace
Business Applications
Microsft 365
Technologies
Power Platform
Contact Information


contactus@kumonix.com


Phone
020 4622 0001


Office
Kumonix Ltd
86-90 Paul Street, London, EC2A 4NE
