HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows Update Windows UpdateCBSPending RebootRegistryPowerShellServicing StackConfigMgrTroubleshooting

"Pending reboot" has at least five sources and your tooling probably checks one

IA
Imran Awan
23 August 2026

An update installs cleanly. The device reports no restart required. Three weeks later your vulnerability scanner is still flagging the CVE that patch was supposed to close.

Or the mirror image: a laptop has reported restart pending for eleven days, has been rebooted six times, and every new cumulative update on it fails.

Both are the same defect, and it is almost never in Windows. It is in the thing doing the checking. "Pending reboot" is not a flag. It is a minimum of five independent markers, each owned by a different component, written at different times and cleared by different code. Most RMM and compliance tools check one.

The short version

What is covered

  1. The problem: one flag checked, five that matter
  2. Why it happens: five owners, one label
  3. How to verify: a read-only sweep of every source
  4. The fix: match the remedy to the marker that fired
  5. Proof it worked: what a clean device looks like
  6. References

The problem: one flag checked, five that matter

This failure has two shapes that look like opposites. They are the same blind spot seen from two sides.

The false negative. Your report says the KB is installed, Get-HotFix agrees, the device says no restart required. But the binaries on disk are still the old ones, because the replacement was deferred to boot and that boot never drained the queue. The patch is registered, not in effect.

The false positive. A device reports reboot-pending permanently. Users reboot; it comes back. Every subsequent update fails, because Windows Update genuinely refuses to install while a mandatory restart is outstanding. That refusal is documented behaviour, not a bug.

Here is the check that ships inside a startling number of monitoring scripts.

The check that lies to you
# The single-source check found in most RMM rules. PS C:\> Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -ErrorAction SilentlyContinue PS C:\> # Nothing returned. Tool concludes: no reboot pending. # The same location, asked correctly: PS C:\> Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" True # A second, unrelated marker the first check never looked at: PS C:\> (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations).PendingFileRenameOperations.Count 14

Read that first command again. It asks for the values inside a container that has no values in it. RebootPending is a key: it exists or it does not, and its existence is the signal. Microsoft's own reference script enumerates subkey names with GetSubKeyNames() and tests for the string RebootPending among them, precisely because there is no value to read.

So the tool returns $null, the rule evaluates to compliant, and the device sails through reporting with fourteen queued file replacements and a blocked servicing stack.

Watch out. The reflex response is to delete the CBS key, or to stop wuauserv and rename SoftwareDistribution. Do neither yet. Both destroy the evidence identifying the stuck package, and neither addresses pending.xml, which is what actually regenerates the flag. You get the same device back tomorrow with no trail to follow.

Why it happens: five owners, one label

There is no single flag because no single component owns "restart". Servicing, Windows Update, the file system, the computer identity and your management agent each have their own reason to want one, and each records it their own way.

Microsoft enumerates this directly. The Microsoft.Windows/RebootPending resource states a reboot may be required due to Windows Updates, Component-Based Servicing, pending file rename operations, pending computer rename, or pending domain join. Five causes, one boolean. That resource is explicitly a proof-of-concept, but its list is the clearest official statement that the answer is a union of independent checks.

The five authoritative sources

SourceOwning componentLocation
CBS reboot pendingCBS, via the TrustedInstaller serviceHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing (subkeys)
Windows Update reboot requiredWindows Update AgentHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired (subkey)
Pending file renamesSession Manager, via MoveFileEx callersHKLM\SYSTEM\CurrentControlSet\Control\Session Manager, value PendingFileRenameOperations
Pending computer renameComputer name configuration...\Control\ComputerName\ActiveComputerName vs ...\ComputerName\ComputerName
ConfigMgr client reboot stateConfigMgr client agentWMI: root\ccm\ClientSDK, class CCM_ClientUtilities

A sixth exists where it applies: a pending domain join, recorded by Netlogon under HKLM\SYSTEM\CurrentControlSet\Services\Netlogon. Microsoft's documentation for JoinDomainOrWorkgroup is explicit that the computer must be restarted afterwards.

Inside the CBS parent key

Component-Based Servicing is where most real patching pain lives. Everything below hangs off one parent.

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing

Shared parent key for the table below. All three are subkeys, tested with Test-Path.

Value or subkeyMeaningWhat to look for
RebootPendingStaged work that can only complete during boot, because a component could not be replaced in place.Present at all. Still present after a successful restart means a stuck queue, not a stale flag.
PackagesPendingPackage records awaiting completion. Tells you which KB is stuck.Enumerate its child keys. Names map to KB numbers: your root cause, not a nuisance to delete.
RebootInProgressA servicing reboot was initiated and never concluded.Appears with RebootPending after an interruption, such as a hard power-off during "Working on updates".
Gotcha. The key-versus-value distinction flips between sources, and that inconsistency causes most wrong reboot reporting. CBS RebootPending, CBS PackagesPending and Auto Update\RebootRequired are keys needing Test-Path. PendingFileRenameOperations is a value needing Get-ItemProperty. Use the wrong one and you get a confident, permanent, wrong answer.

Why a stuck CBS flag blocks the next update

This is what turns a cosmetic reporting problem into a patching outage, and it dictates the fix.

When CBS installs a component and a target file is in use, it cannot swap it there and then. It writes the outstanding primitive and advanced installer operations into a transaction file at %windir%\WinSxS\pending.xml, to be applied on the following boot before the files are referenced.

That transaction is why the flag exists. RebootPending is not a reminder to the user; it is the stack recording that it holds an open, incomplete transaction. A servicing stack with an open transaction will not begin a new one, because that would interleave two sets of component changes over the same store.

So the loop is: the queue does not drain, because a file is still locked, store permissions are wrong, or the transaction is damaged. The flag is rewritten. The next cumulative update requests a session, is refused, and fails. Delete the flag by hand and it returns on the next boot, because pending.xml is still there and the stack re-derives its state from the transaction, not from the flag.

Windows Update surfaces the refusal with a documented code. WU_E_INSTALL_NOT_ALLOWED, 0x80240016, is defined in Wuerror.h as an operation that "tried to install while another installation was in progress or the system was pending a mandatory restart." Its benign sibling WU_S_REBOOT_REQUIRED, 0x00240005, means the system must be restarted to complete installation. Repeated 0x80240016 on one device points at a stuck transaction rather than content or connectivity.

Context. This is also why a device reports the KB as installed while the patch is not in effect. Package registration and physical file replacement are separated by a boot. The Setup log records the intermediate state honestly: on the lab device used here, Event 2 reads "Package <KB> was successfully changed to the Staged state". Staged is not installed. A device sitting at staged with an open transaction is one your inventory calls patched and your scanner calls vulnerable, and the scanner is right.

The binaries involved

BinaryRoleLocation
TrustedInstaller.exeWindows Modules Installer service. Owns the component store and writes the CBS markers. Legitimately Stopped when idle.%windir%\servicing
cbscore.dllServicing stack core, loaded by TrustedInstaller. Implements session handling, so this is the code that refuses a new session while a transaction is open.%windir%\System32
TiWorker.exeWindows Modules Installer Worker. Does the component work; the process burning CPU during servicing.%windir%\WinSxS
poqexec.exePrimitive operations queue executor. Applies the deferred operations at boot.%windir%\System32
wuaueng.dllWindows Update Agent engine. Owns the Auto Update\RebootRequired marker. Lab device: 1509.2607.1012.0.%windir%\System32

TrustedInstaller and the operations it performs write to %windir%\Logs\CBS\CBS.log, where you go once the registry has told you which marker fired.

Tip. TrustedInstaller showing as Stopped is not a fault, and is the most common false alarm here. On the clean Windows 11 lab device, the healthy idle baseline was wuauserv=Running/Manual, bits=Running/Automatic, cryptsvc=Running/Automatic, UsoSvc and DoSvc=Running/Automatic, and trustedinstaller=Stopped/Manual. It is demand-start. Do not "fix" it.

How to verify: a read-only sweep of every source

Work through this in order. Every step is read-only. You are identifying which marker fired, because that determines the fix, and a wrong guess turns a five-minute job into a reimage.

  1. Establish whether a restart actually happened. Check the System log for User32 Event 1074, which records a planned restart with the requesting process and a reason code. If the device genuinely never restarted, you have a compliance problem, not a servicing one.
  2. Sweep all markers at once with the script below. Never check them one at a time; the point is seeing which ones disagree.
  3. Only Auto Update\RebootRequired set, CBS clean: an ordinary Windows Update restart still owed. Benign.
  4. Only PendingFileRenameOperations populated: read its contents first. This is usually a third-party installer or AV update, not Windows servicing, and clears on the next boot.
  5. CBS RebootPending set: check whether %windir%\WinSxS\pending.xml exists and enumerate PackagesPending. This is the branch that blocks future updates, and those two artefacts name the stuck package.
  6. CBS RebootPending persisted through a confirmed restart (an Event 1074 after the flag was set): a stuck transaction. Go to CBS.log and search for the package named in PackagesPending.
  7. Markers clean but ConfigMgr still reports pending: the client's state is stale and the fix belongs on the agent, not in the registry.

The script below checks every source in one pass and reports which fired. It reads only; there is no remediation in it by design.

Get-PendingRebootSources.ps1 (read-only)
# Read-only. Reports WHICH pending-reboot marker fired. Changes nothing. # Run elevated: some CBS subkeys are not readable as a standard user. $r = [ordered]@{ ComputerName = $env:COMPUTERNAME } # 1. CBS - these are SUBKEYS. Test-Path, never Get-ItemProperty. $cbs = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing' $r.CBS_RebootPending = Test-Path (Join-Path $cbs 'RebootPending') $r.CBS_PackagesPending = Test-Path (Join-Path $cbs 'PackagesPending') $r.CBS_RebootInProgress = Test-Path (Join-Path $cbs 'RebootInProgress') # The servicing transaction itself. This is what regenerates the flag. $r.PendingXml = Test-Path (Join-Path $env:windir 'WinSxS\pending.xml') # 2. Windows Update Agent - also a subkey, not a value. $au = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update' $r.WU_RebootRequired = Test-Path (Join-Path $au 'RebootRequired') # 3. Session Manager - this one IS a value, type REG_MULTI_SZ. $sm = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' $pfro = (Get-ItemProperty -Path $sm -Name PendingFileRenameOperations ` -ErrorAction SilentlyContinue).PendingFileRenameOperations $r.PendingFileRename = [bool]$pfro if ($pfro) { $r.PendingFileRenameCount = $pfro.Count } else { $r.PendingFileRenameCount = 0 } # 4. Computer rename pending - active name vs name after next boot. $cn = 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName' $active = (Get-ItemProperty "$cn\ActiveComputerName" -Name ComputerName -ErrorAction SilentlyContinue).ComputerName $next = (Get-ItemProperty "$cn\ComputerName" -Name ComputerName -ErrorAction SilentlyContinue).ComputerName $r.RenamePending = [bool]($active -and $next -and ($active -ne $next)) $r.RenameFromTo = "$active -> $next" # 5. ConfigMgr client, only where the client is installed. $r.CCM_RebootPending = 'n/a (no ConfigMgr client)' if (Get-CimInstance -Namespace 'root\ccm\ClientSDK' -ClassName CCM_ClientUtilities -ErrorAction SilentlyContinue) { $ccm = Invoke-CimMethod -Namespace 'root\ccm\ClientSDK' -ClassName CCM_ClientUtilities ` -MethodName DetermineIfRebootPending $r.CCM_RebootPending = $ccm.RebootPending $r.CCM_IsHardRebootPending = $ccm.IsHardRebootPending } [pscustomobject]$r | Format-List

Two design choices matter. The CBS and Auto Update checks use Test-Path because their markers are keys; Session Manager uses Get-ItemProperty because its marker is a value. Mixing those up is the original sin of every broken reboot report.

The ConfigMgr branch is guarded because root\ccm\ClientSDK does not exist on an Intune-only device, where an unguarded call throws.

Here is the output from a device in the bad state, where the flag outlived a restart.

Output: stuck servicing transaction
ComputerName : WKS-4471 CBS_RebootPending : True CBS_PackagesPending : True CBS_RebootInProgress : False PendingXml : True WU_RebootRequired : False PendingFileRename : False PendingFileRenameCount : 0 RenamePending : False RenameFromTo : WKS-4471 -> WKS-4471 CCM_RebootPending : n/a (no ConfigMgr client) # WU_RebootRequired is False - the agent believes it is finished. Only # CBS disagrees, and pending.xml confirms why: an open transaction. # A tool checking only the WindowsUpdate marker calls this healthy.

CBS set with Windows Update clear is the signature of the blocked-servicing case, and exactly what a single-source check misses most often, because many tools check the WindowsUpdate\Auto Update location rather than the CBS one.

Now name the stuck package, still read-only.

Identifying the stuck package and queued renames
# Which package is holding the transaction open? PS C:\> Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending' | >> Select-Object -ExpandProperty PSChildName Package_for_KB5123304~31bf3856ad364e35~amd64~~26200.9168.1.0 # Correlate against the servicing log. Never open CBS.log in Notepad; # it is routinely hundreds of MB. Filter it. PS C:\> Select-String -Path "$env:windir\Logs\CBS\CBS.log" -Pattern 'KB5123304' -SimpleMatch | >> Select-Object -Last 5 # Source then destination. A blank destination means DELETE. PS C:\> (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' ` >> -Name PendingFileRenameOperations).PendingFileRenameOperations \??\C:\Program Files\Vendor\agent.dll.tmp \??\C:\Program Files\Vendor\agent.dll

That format is frequently misread as a list of single files. It is a sequence of null-terminated pairs: source then destination is a rename on boot, source then an empty entry is a delete on boot. Session Manager processes them in issue order, and entries come from any process calling MoveFileEx with the delay-until-reboot flag.

Above, that is a vendor agent replacing its own DLL, not Windows servicing: clearing the CBS key would do nothing for it.

Event ID catalog

All of the below is one channel: Microsoft-Windows-WindowsUpdateClient/Operational (Event Viewer: Applications and Services Logs, Microsoft, Windows, WindowsUpdateClient, Operational).

Event IDMessageWhat it tells you
26Windows Update successfully found N updatesDetection works and the agent reaches its source. Confirmed on the lab device.
44Windows Update started downloading an updateTransfer began. No later 41 points at BITS or delivery, not a reboot problem.
41An update was downloadedContent is on disk. Confirmed on the lab device. Failures past here are servicing, not networking.
43Installation Started: Windows has started installing the following updateThe agent handed off to the servicing stack. A 43 with no matching 19 is where stuck transactions live.
19Installation Successful: Windows successfully installed the following updateThe agent's view of success. It can be logged while the change is only staged, so a 19 is not proof the patch is in effect.

That last row is the false negative in one line. Event 19 plus a CBS RebootPending that never clears is a device your inventory calls patched and your scanner calls vulnerable.

The fix: match the remedy to the marker that fired

There is no single fix, because there was no single cause. Take the branch your diagnostic landed on.

Only Auto Update\RebootRequired. Restart the device. That is the whole fix. Do not touch the registry; this marker is the agent doing its job correctly.

Only PendingFileRenameOperations. Read the pairs, identify the owning product, restart. If it repopulates every boot with the same pairs, the fault is that vendor's installer. Do not delete the value: you would be cancelling a file replacement some product depends on, occasionally half of an update.

A computer rename is pending. Restart. To cancel it instead, set the value under the ComputerName key back to the currently active name so the two agree. Correct the configuration, do not delete the key.

CBS RebootPending set, no restart yet since servicing. Restart properly and re-run the diagnostic. A single clean boot resolves most of these, and everything below is then unnecessary.

CBS RebootPending survived a confirmed restart. This is the real case, and order of operations matters:

  1. Capture evidence first. Save the PackagesPending subkey names, copy %windir%\Logs\CBS\CBS.log aside, note whether pending.xml exists. If this escalates to Microsoft, that is the package they will ask for.
  2. Install the latest Servicing Stack Update. The stack repairs itself more often than people expect, an SSU is the documented first move for TiWorker and CBS failures, and it is the least invasive item here.
  3. Let the transaction complete on its own terms. Reboot once more and leave the device at "Working on updates" without interrupting. poqexec.exe needs that window to drain the queue.
  4. Then repair the component store. DISM /Online /Cleanup-Image /RestoreHealth, then SFC /ScanNow, in that order. SFC alone cannot repair a store whose own payload is damaged.
  5. Treat deleting the CBS keys and pending.xml as a last resort, done knowingly and with a backup. It gets the device installing again, but it abandons an in-flight component transaction: expect to validate the affected KB and to reinstall the package the transaction belonged to.

Markers clean but ConfigMgr still pending. The client's cached state is stale. Trigger the client's own evaluation; never edit registry markers to make the agent happier. That is not where the client stores its state, and you would be lying to five other consumers to satisfy one.

Gotcha. Do not build remediation into your detection script. A monitoring rule that clears reboot flags is not a monitoring rule, and once it has run fleet-wide you have permanently lost the ability to distinguish a genuine stuck transaction from a normal restart owed. Detect and report; remediate separately and deliberately, with the package name captured first.

Proof it worked: what a clean device looks like

Verify with the same read-only sweep, not by the device reporting itself compliant.

For reference, here is genuinely clean. Captured read-only from a live Windows 11 corporate device, build 26200.9168, during preparation for this article; all three primary markers were verified absent.

Verified clean baseline (real lab device)
ComputerName : (lab device, Windows 11 build 26200.9168) CBS_RebootPending : False CBS_PackagesPending : False CBS_RebootInProgress : False PendingXml : False WU_RebootRequired : False PendingFileRename : False PendingFileRenameCount : 0 RenamePending : False CCM_RebootPending : n/a (no ConfigMgr client) # Measured on the real device: CBS RebootPending, the WindowsUpdate # Auto Update RebootRequired marker, and Session Manager # PendingFileRenameOperations were all absent. wuaueng.dll 1509.2607.1012.0. # Most recent KBs installed: KB5123304, KB5121003, KB5120708.

Three things make that a real verification rather than a hopeful one.

Every marker is reported, not just the failing one. A pass is all sources clean at once. Reporting only the marker you chased is how devices get closed out with a second flag still set.

pending.xml is gone, not just the flag. If the flag cleared but the transaction file remains, nothing is fixed and the flag returns on the next boot. That line is the difference between a fix and a reset.

A subsequent update installs. Trigger a scan, confirm an Event 26 followed by a 41, and confirm 0x80240016 is gone.

Tip. Turn the diagnostic into fleet-wide detection and report every marker as its own column, never as one aggregated boolean. Collapsing six independent signals into a single true/false rebuilds the exact blind spot this article is about. Separate columns also make patterns obvious at scale: CBS set with Windows Update clear across a group of devices usually means one bad package, not eleven bad laptops.

References

Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows Update
One read-only PowerShell collector for Windows patching failures…
Test-Path and value checks return confidently wrong patching verdicts on real devices.…
Windows Update
The Windows patching triage decision tree: which log, which key,…
Route each patching symptom to the one evidence source that answers it. Then learn the…
Windows Update
Which Update Service Is This Device Actually Registered Against?…
Before troubleshooting why a device gets the wrong updates, enumerate the registered…