Detect Windows Update Service Problems with PowerShell · CloudEngineerHub
Detection & Remediation9 min read4 views
Detecting Windows Update Service Problems with PowerShell
Find devices where wuauserv, BITS, CryptSvc, or msiserver were disabled or broken, and restore their documented start modes with a conservative remediation script.
C
CloudEngineerHub Team
Published: September 17, 2026· Last Updated: September 28, 2026·9 min read
When Windows Update quietly stops working, the cause is very often not the update engine
but the service stack underneath it. The Windows Update service (wuauserv), Background
Intelligent Transfer Service (BITS), Cryptographic Services (CryptSvc), and Windows
Installer (msiserver) form a chain that updates depend on, and hardening scripts, cleanup
tools, and "optimize Windows" utilities love to disable services they cannot identify. A
Disabled wuauserv produces devices that never scan, never report update status to Intune,
and silently fall out of your patch compliance targets.
Visual Walkthrough
The engine behind every “Detect with PowerShell” runbook on this site.
Exit 1 flips the device into the remediation queue for this package.
remediate
3
Remediation executes
Fix script runs silently as SYSTEM with a 5-minute budget.
verify
4
Re-run detection
The same detection script must now exit 0 — proof, not hope.
telemetry
5
Results report
Per-device outcome lands in Reports → Remediations for trend analysis.
6
Repeat on schedule
The loop continues — drift gets caught the day it appears.
Continuous cycle
Proactive Remediations — The Detect → Fix → Verify Loop. 1. Detection script runs: Scheduled (daily/hourly): exit 0 healthy, exit 1 unhealthy — nothing more. — 2. Verdict: unhealthy: Exit 1 flips the device into the remediation queue for this package. — 3. Remediation executes: Fix script runs silently as SYSTEM with a 5-minute budget. — 4. Re-run detection: The same detection script must now exit 0 — proof, not hope. — 5. Results report: Per-device outcome lands in Reports → Remediations for trend analysis. — 6. Repeat on schedule: The loop continues — drift gets caught the day it appears.
C
CloudEngineerHub Team
Author
The CloudEngineerHub editorial team — Microsoft endpoint management and cloud engineers writing hands-on guides on Intune, Azure, Entra ID, Autopilot, Defender and PowerShell. Every article is reviewed against current Microsoft documentation.
This article gives you a paired PowerShell detection and remediation set for the Windows
Update service stack. The detection script audits the four services for Disabled start
modes and missing registrations, and collects recent Service Control Manager crash events
as context. The remediation script restores the documented Windows default start modes,
starts what it re-enabled to prove the recovery, and deliberately leaves healthy
trigger-start services alone.
Both scripts are built for Intune Scripts and Remediations: 64-bit SYSTEM context,
structured logging to C:\ProgramData\Company\Logs, idempotent behavior, and exit codes
that map cleanly to device status in the admin center.
Symptoms
Service stack problems show up as update silence rather than errors:
Update compliance reports show devices with no scan status for weeks while the devices check in to Intune normally.
Manual checks in Settings → Windows Update show errors, or the page spins without finding updates.
Windows Installer operations fail on devices that previously worked, pointing at msiserver problems.
In services.msc, wuauserv or BITS appear with startup type Disabled, or are missing entirely.
The System event log shows Service Control Manager crash events for update services repeating over time.
A useful confirmation: on a suspect device, run sc qc wuauserv at an elevated prompt and
compare the START_TYPE against the documented default (DEMAND_START for wuauserv on
Windows 10+). Anything disabled is your smoking gun.
Possible Causes
Deliberate service disabling by hardening tooling
Security baselines written by different teams sometimes disagree: one script disables
"wuauserv" to stop reboots, another assumes updates work. Devices that ran the disabling
script stay broken until something re-enables the service.
Corruption after failed updates or disk issues
A failed servicing operation can leave services in odd states, especially after disk space
exhaustion or an interrupted boot. The services themselves are usually intact; their
configuration or dependencies are not.
Missing services after image capture or repair
Golden images captured from heavily modified sources, or dism repair operations gone
wrong, can leave service registrations missing entirely, which is a more serious state
than a Disabled service.
Crash-looping services
A service that starts and crashes repeatedly (Service Control Manager events 7031/7034 in
the System log) will look enabled but never stay up. Detection can surface the evidence;
a crashing service needs its own investigation.
Detection Script
The script below is read-only and completes in seconds. It audits the four services for
presence, start mode, and running state, and pulls recent Service Control Manager crash
events for wuauserv as context.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#Requires -RunAsAdministrator
[CmdletBinding()]
param()
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
<#
.SYNOPSIS
Detection script: audits the Windows Update service stack (wuauserv,
BITS, CryptSvc, msiserver) for Disabled start modes and missing services,
and reports recent Service Control Manager crash events for wuauserv.
.NOTES
Intended for Intune Scripts and Remediations, 64-bit SYSTEM context.
Exit 0 = no service has a Disabled start mode; none are missing.
Exit 1 = at least one update service is Disabled or missing.
Exit 3 = unexpected error.
DESIGN NOTES, stated honestly:
- wuauserv is Manual (trigger-started) on Windows 10+, so a stopped but
enabled wuauserv is often normal between scans and is logged as
context, not as a failure.
- msiserver is a demand-start service; stopped outside installations is
its normal state.
- Crash events (7031/7034) are logged as WARN evidence for humans;
a script start cannot fix a crashing service, so they do not change
the exit code on their own.
#>$logDir = 'C:\ProgramData\Company\Logs'$logFile = Join-Path $logDir'UpdateServicesDetection.log'# Expected start modes on Windows 10/11, in Win32_Service StartMode vocabulary.$updateServices = @(
@{ Name = 'wuauserv'; Label = 'Windows Update (wuauserv)'; CimStartMode = 'Manual' },
@{ Name = 'BITS'; Label = 'Background Intelligent Transfer (BITS)'; CimStartMode = 'Auto' },
@{ Name = 'CryptSvc'; Label = 'Cryptographic Services (CryptSvc)'; CimStartMode = 'Auto' },
@{ Name = 'msiserver'; Label = 'Windows Installer (msiserver)'; CimStartMode = 'Manual' }
)
function Write-DetectionLog {
param([Parameter(Mandatory)][string] $Level, [Parameter(Mandatory)][string] $Message)
if (-not (Test-Path $logDir)) { New-Item -Path$logDir -ItemType Directory -Force | Out-Null }
"$([DateTime]::UtcNow.ToString('o')) [$Level] $Message" | Out-File -FilePath$logFile -Append -Encoding utf8
}
try {
Write-DetectionLog 'INFO''Windows Update service detection run started.'$issues = @()
# ---- Check 1: each service present, start mode not Disabled ----foreach ($svcDefin$updateServices) {
$svc = Get-CimInstance -ClassName Win32_Service -Filter"Name='$($svcDef.Name)'"if ($null -eq$svc) {
Write-DetectionLog 'ERROR'"$($svcDef.Label) service is not present on this device."$issues += "$($svcDef.Label) service is absent"continue
}
Write-DetectionLog 'INFO'"$($svcDef.Label): Status=$($svc.Status) StartMode=$($svc.StartMode) (expected start mode: $($svcDef.CimStartMode))"if ($svc.StartMode -eq'Disabled') {
Write-DetectionLog 'ERROR'"$($svcDef.Label) start type is Disabled, expected $($svcDef.CimStartMode). Updates cannot function."$issues += "$($svcDef.Label) start type is Disabled"continue
}
# Stopped-state context, by service:if ($svcDef.Name -eq'msiserver' -and$svc.Status -ne'Running') {
Write-DetectionLog 'INFO''msiserver is demand-started; stopped outside installations is its normal state.'
}
elseif ($svc.Status -ne'Running') {
Write-DetectionLog 'WARN'"$($svcDef.Label) is stopped while enabled. Trigger-start services idle out to Stopped between operations; logged as context."
}
}
# ---- Check 2: recent Service Control Manager crash events for wuauserv ---- # 7031 = service terminated unexpectedly; 7034 = terminated repeatedly.$crashEvents = @(Get-WinEvent -FilterHashtable @{ LogName = 'System'; ProviderName = 'Service Control Manager'; Id = @(7031, 7034); StartTime = (Get-Date).AddDays(-14) } -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match'Windows Update' })
if ($crashEvents.Count -gt0) {
Write-DetectionLog 'WARN'"Found $($crashEvents.Count) SCM crash event(s) (7031/7034) mentioning Windows Update in the last 14 days; most recent at $($crashEvents[0].TimeCreated.ToString('o'))."
Write-DetectionLog 'WARN''Crashes are evidence for human follow-up: if the service crashes on start, the remediation start attempt will fail and the event log will show why.'
}
else {
Write-DetectionLog 'INFO''No Service Control Manager crash events for Windows Update in the last 14 days.'
}
if ($issues.Count -gt0) {
Write-DetectionLog 'INFO''Update service detection finished with issue(s).'
exit 1
}
Write-DetectionLog 'INFO''Update service stack healthy (no Disabled start modes, no missing services).'
exit 0
}
catch {
Write-DetectionLog 'ERROR'"Unexpected failure: $($_.Exception.Message)"
exit 3
}
finally {
Write-DetectionLog 'INFO''Windows Update service detection run finished.'
}
Detection Logic
Service inventory. For each of wuauserv, BITS, CryptSvc, and msiserver the script
reads presence, the configured start mode through a Win32_Service CIM query, and the
current status. A completely missing service is the most severe finding and is reported
as such.
Disabled start modes. The design note in the script header is important: wuauserv
is Manual and trigger-started on Windows 10 and 11, so a stopped-but-enabled wuauserv
between scans is normal and is logged as context, not failure. A Disabled start mode is
never normal for any of the four services and always produces a finding.
Crash evidence. Recent System log events 7031 and 7034 for wuauserv are logged as
WARN context. The detection does not fail the device on crash evidence alone, because a
crashing service needs human diagnosis; but the events in the log point you straight at
the problem when you triage.
Classification. Any Disabled or missing service exits 1. All four services missing
is treated separately in remediation, and any unexpected error exits 3.
Every check writes to C:\ProgramData\Company\Logs\UpdateServicesDetection.log with the
measured start modes and statuses, so the log alone can answer "what was wrong" weeks
later.
Remediation Script
The remediation restores documented Windows defaults: wuauserv, BITS, and msiserver back
to Manual, CryptSvc to Automatic. Services that were Disabled get one start attempt to
prove the recovery in the log. Stopped-but-enabled services are deliberately left alone,
because forcing wuauserv to run permanently fights the platform's trigger-start design.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#Requires -RunAsAdministrator
[CmdletBinding()]
param()
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
<#
.SYNOPSIS
Remediation script: restores documented default start modes for the
Windows Update service stack and restarts services it had to re-enable.
.DESCRIPTION
Scope of this script (deliberately conservative):
- Windows Update services that are Disabled are set back to their
documented Windows defaults: wuauserv/BITS/msiserver = Manual,
CryptSvc = Automatic. These match the factory start modes on
Windows 10 and 11; the script never "upgrades" a healthy Manual
service to Automatic, because trigger-start design is intentional.
- A service that was Disabled is started once after re-enabling so the
repair is provable in the log.
- Stopped-but-enabled services are NOT started: a stopped wuauserv
between scans is normal on Windows 10+ (trigger start), and forcing
it would fight the platform design.
The script never deletes anything, never touches update state folders
(see the companion components-reset remediation for that heavier flow),
and never edits policy. If a hardening policy disabled these services on
purpose, this script will fight it every run - that conflict is a policy
conversation, not a script problem, and the log will show it clearly.
Exit 0 = no action needed or repairs applied and verified.
Exit 1 = a service could not be re-enabled or started.
Exit 2 = none of the managed services exist (unexpected OS state).
Exit 3 = unexpected error.
#>$logDir = 'C:\ProgramData\Company\Logs'$logFile = Join-Path $logDir'UpdateServicesRemediation.log'# Service -> documented Windows default start mode (Windows 10/11 factory).$serviceDefaults = [ordered] @{
'wuauserv' = 'Manual''BITS' = 'Manual''msiserver' = 'Manual''CryptSvc' = 'Automatic'
}
function Write-RemediationLog {
param([Parameter(Mandatory)][string] $Level, [Parameter(Mandatory)][string] $Message)
if (-not (Test-Path $logDir)) { New-Item -Path$logDir -ItemType Directory -Force | Out-Null }
"$([DateTime]::UtcNow.ToString('o')) [$Level] $Message" | Out-File -FilePath$logFile -Append -Encoding utf8
}
try {
Write-RemediationLog 'INFO''Update services remediation run started.'$missing = @()
$repaired = @()
foreach ($namein$serviceDefaults.Keys) {
$service = Get-Service -Name$name -ErrorAction SilentlyContinue
if ($null -eq$service) {
$missing += $name
Write-RemediationLog 'ERROR'"Service '$name' is not installed - unexpected OS state."continue
}
$startMode = (Get-CimInstance -ClassName Win32_Service -Filter"Name='$name'").StartMode
$expected = $serviceDefaults[$name]
if ($startMode -eq'Disabled') {
Write-RemediationLog 'INFO'"Service '$name' is Disabled - restoring default start mode '$expected'."
Set-Service -Name$name -StartupType$expected -ErrorAction Stop
$repaired += $name # Prove the recovery with a single start for services that can run on demand.try {
Start-Service -Name$name -ErrorAction Stop
Write-RemediationLog 'INFO'"Service '$name' started successfully after re-enable."
}
catch {
# msiserver and trigger-start services can refuse an explicit start; not fatal.
Write-RemediationLog 'WARN'"Service '$name' re-enabled but explicit start failed: $($_.Exception.Message)"
}
}
else {
Write-RemediationLog 'INFO'"Service '$name' start mode '$startMode' (status: $($service.Status)) - no change."
}
}
if ($missing.Count -eq$serviceDefaults.Count) {
Write-RemediationLog 'ERROR''No update services found at all - device state is unexpected.'
exit 2
}
if ($repaired.Count -gt0) {
Write-RemediationLog 'INFO'"Repaired services: $($repaired -join ', ')"
}
else {
Write-RemediationLog 'INFO''All update services already match documented defaults - device compliant.'
}
exit 0
}
catch {
Write-RemediationLog 'ERROR'"Remediation failed: $($_.Exception.Message)"
exit 3
}
If a hardening policy disabled these services on purpose, this script will conflict with
it on every run. That is not a script bug; it is a policy conversation, and the log makes
the conflict visible instead of hiding it.
Deploying Through Intune
In the Microsoft Intune admin center, go to Devices → Scripts and remediations → + Add, platform Windows 10/11.
Name it explicitly, for example Remediate - Windows Update service stack, and describe the blast radius ("restores default start modes for wuauserv, BITS, CryptSvc, msiserver; never deletes update state").
Upload detect.ps1 on the Detection script tab with Run script in 64-bit PowerShell: Yes and Run this script using signed-on credentials: No.
Upload remediate.ps1 on the Remediation script tab with the same settings.
Schedule Weekly. Service tampering is usually a one-time event per device, so weekly detection catches it promptly without burning resources; tighten to Daily during a hardening-tool rollout.
Assign to your Windows device rings, starting with a test ring. If parts of your estate intentionally run alternative servicing (rare, but real), exclude them explicitly.
Notes for this package:
Signed-on credentials: No. Service configuration is machine-scoped.
Keep this remediation focused on start modes. For corrupt download stores and deeper
component damage, use the companion components-reset remediation instead of widening
this script.
Visual Walkthrough
Why the order of servicing stack and cumulative updates matters.
Offline servicing completes; Windows reports the new revision.
Windows Servicing Stack — SSU + LCU Anatomy. 1. SSU first: Servicing Stack Update upgrades the updater itself. — 2. LCU delivered: Latest Cumulative Update rides on top of a healthy SSU. — 3. CBS transaction: Component-Based Servicing stages payloads transactionally. — 4. Pending reboot markers: Registry markers hold the state until restart. — 5. Finalize on reboot: Offline servicing completes; Windows reports the new revision.
Exit Codes
Code
Meaning
0
All services present with healthy start modes (detection) — or defaults restored and verified (remediation)
1
At least one update service is Disabled or missing (detection) — remediation exit 1 means a service could not be re-enabled or started
2
Remediation found none of the managed services — unexpected OS state, needs human review
Lines are UTC-timestamped and leveled. Detection records every service's start mode and
status plus any crash events found; remediation records each restored start mode and the
post-repair start result. Together they answer both "what is wrong now" and "what was
wrong when we fixed it".
Troubleshooting the Script
Detection flags healthy devices. Confirm the script runs in 64-bit PowerShell and
that nothing in your environment remaps service queries. The script reads start modes
via CIM, which is stable across builds; a flag on every device usually means the
script is not the problem, the baseline is.
Remediation restores the mode but it flips back to Disabled. A policy or scheduled
task in your environment is re-disabling the service. The log will show the pattern;
find and fix the source rather than scheduling more repairs.
Crash events fill the log. Events 7031/7034 on wuauserv mean the service starts and
dies. Check dependency health (BITS, RPC), run the system file checker flow your
organization prefers, and treat repeated crashes as a component repair case.
Exit 2 on remediation. Service registrations are genuinely missing. That is image
or OS repair territory: capture the state, then service-stack or in-place repair per
your organization's process.
No log file. The package never ran: verify assignment, check-in, and script context
settings, especially 64-bit enforcement.
How to Validate the Fix
On a flagged device, run detect.ps1 manually in an elevated 64-bit console; expect
exit 1 with the offending service named in the log.
Run remediate.ps1; expect exit 0 with a log line naming the repaired services.
Run detection again; it must return 0 with all four services at documented defaults.
Trigger a scan (Settings → Windows Update → Check for updates) and confirm the device
scans without error.
In Intune, confirm the device reports "Remediated" or "Compliant" for the package and
that update compliance reporting recovers on the next cycle.
Production Considerations
Execution context. Both scripts run as SYSTEM in 64-bit Windows PowerShell. Service
configuration requires admin rights, which SYSTEM provides.
Idempotency. Detection is read-only. Remediation changes only start modes that
differ from documented defaults and skips everything else, so repeated runs are safe.
Side effects. Restoring a start mode takes effect at the next trigger or boot; the
script's single start attempt after re-enabling is enough to prove recovery without
forcing services to run permanently. No files are deleted, no reboots are scheduled.
Security. No credentials are embedded and no policy values are edited. If your
security team deliberately disables update services on some devices, exclude those
devices from this package rather than fighting policy. Have your PowerShell automation
SME and security team review and test-ring validate the scripts before broad rollout.
Change discipline. The remediation's default start modes match Windows 10 and 11
factory values; if Microsoft changes defaults in a future build, review the mapping
before letting the script manage new OS versions.
Why not just set wuauserv to Automatic so updates always work?
Because on Windows 10 and 11 wuauserv is designed to be Manual and trigger-started: the
system starts it when a scan is needed. Forcing it to Automatic masks design intent, hides
trigger problems, and is exactly the kind of well-meaning change that hardening teams push
back on. Restoring the documented default is both safer and more defensible.
The services are fine but updates still fail. What should I check next?
Service health is necessary but not sufficient. Move to the companion posts: check for
failed update history entries, pending updates stuck in a broken state, or a corrupt
download store that needs the components reset. The detection log from this post rules the
service stack out, which narrows the search.
Can hardening policies and this remediation coexist?
Not on the same devices. If a policy intentionally disables update services, this package
will report and repair it every cycle. That conflict is valuable visibility during a
transition, but the end state should be an explicit decision: either exclude those devices
from this package or change the policy. Silent fights between scripts and policy are how
fleets drift.
Comments
0No comments yet — be the first to share your thoughts.