HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows 11 Windows 11WinSxSComponent StoreDISMSFCCBSServicingWindows UpdateTrustedInstallerIntune

The component store is corrupt, so every update fails: what WinSxS actually is, and what DISM and SFC really do to it

IA
Imran Awan
21 August 2026

Something goes wrong with Windows Update, and within about ninety seconds somebody says "run SFC, then run DISM". It is the most repeated advice in Windows administration. It is also, in that order, backwards. And almost nobody saying it can tell you what either tool actually touches.

The short version

C:\Windows\WinSxS is the Windows component store, not a folder of duplicate files. Microsoft documents that most of what Explorer counts there is hard links, so the folder is far smaller than it looks, and Dism /Online /Cleanup-Image /AnalyzeComponentStore is the documented way to get the real number. System File Checker repairs live Windows files from the component store, so if the store itself is broken SFC has nothing good to copy, which is why Microsoft's own support article runs DISM /RestoreHealth before sfc /scannow. And /CheckHealth is not a scan: it only reads a flag a previous failed operation set, which is why it can disagree with /ScanHealth on the same machine.

The problem: every update fails and WinSxS looks enormous

Two complaints arrive together often enough that they feel like one problem.

The first is that updates stop installing. A cumulative update downloads, stages, then rolls back. Enabling an optional feature fails. The error is usually 0x800f081f or 0x800f0922. Nothing in the Windows Update user interface explains why.

The second is a disk-space complaint. Somebody sorts C:\Windows by size in File Explorer and finds a folder called WinSxS using more space than everything else combined. On the machine I used to write this article, Explorer reports 24.81 GB.

Both complaints lead to the same two commands being typed, usually in the wrong order, usually with no idea what they do. So before any command, three questions need answers.

  1. What is the component store, and why does an update fail when it is damaged?
  2. How big is it really, as opposed to how big Explorer says it is?
  3. Which of the DISM switches read, which repair, and which permanently destroy your ability to uninstall an update?
Context: "SxS" stands for side-by-side. The component store was introduced in Windows XP to support side-by-side assemblies, so that two applications could each use their own version of the same library. Microsoft documents that from Windows Vista onwards it was expanded to track and service every component that makes up the operating system. The name stayed. The job changed completely.

Why it happens: WinSxS is the component store, not a junk drawer

What the component store actually is

Microsoft states the location plainly: the WinSxS folder is "the location for Windows Component Store files", and the component store "is used to support the functions needed for the customization and updating of Windows". It then lists what depends on it.

Documented dependencyWhat breaks without a healthy store
Using Windows Update to install new component versionsCumulative updates fail or roll back
Enabling or disabling Windows featuresOptional features cannot be turned on
Adding roles or features using Server ManagerRole installation fails
Moving systems between different Windows editionsEdition upgrade fails
System recovery from corruption or boot failuresRepair has no known-good source
Uninstalling problematic updatesYou cannot roll a bad update back
Running programs using side-by-side assembliesApplications fail to load their libraries

Read the last two rows again. The store is not only how updates go on. It is also how they come off. That is the single most important thing to understand before you run any cleanup command.

The chain, from trigger to result

Here is the order things happen in. Every arrow is one component handing off to the next.

  1. An update package arrives, as a .msu or .cab. Microsoft documents that specific versions of components are collected together into packages, and that packages are what Windows Update and DISM use to update Windows.
  2. The package is described by manifest and catalogue files. On a live device these sit as .mum and .cat files under C:\Windows\servicing\Packages. On the machine I checked there were 14,980 of them.
  3. The servicing stack reads that metadata. The component-based servicing engine, CBS, decides what needs to change.
  4. Component versions are placed into C:\Windows\WinSxS, one directory per component version. That machine had 30,125 of them and 43,198 files under WinSxS\Manifests.
  5. The live operating system directories, such as C:\Windows\System32, are pointed at the correct version using NTFS hard links.
  6. A reboot commits any change that could not be made while the files were in use.

If step 4 is incomplete, step 5 has nothing to point at, and step 3 refuses to proceed. That is component store corruption in one sentence. The store says a component should exist; the payload for it does not.

Hard links, and why Explorer lies about the size

This is the part that gets WinSxS deleted by people who should know better. A hard link is, in Microsoft's words, "a file system object which allows two files to refer to the same location on disk". One set of bytes, two paths. Explorer counts both paths.

Microsoft gives a worked example. Directory A holds 1.txt, 2.txt and 3.txt. Directory B holds 4.txt. Files 1 and 2 are hard linked together and hold 1 MB. Files 3 and 4 are hard linked together and hold 2 MB. So how big is directory A? Microsoft gives three different correct answers.

What you are doingDocumented answer
Reading every file in it4 MB, the sum of each file size
Copying it somewhere else3 MB, the sum of the hard-linked data
Deleting it to free space1 MB, because only that much is linked from A alone

Microsoft then says which of the three applies to WinSxS: "The third answer in the directory A example, most closely matches how much extra space is used." Files hard linked to the rest of the system are needed for the system to run, so they should not be counted at all.

You can watch this happen on your own machine. Microsoft's older troubleshooting article uses advapi32.dll as its example, so here is that exact file on a real Windows 11 device.

PowerShell - run elevated
fsutil hardlink list C:\Windows\System32\advapi32.dll # Lists every path that points at this one set of bytes on disk. \Windows\WinSxS\amd64_microsoft-windows-advapi32_31bf3856ad364e35_10.0.26100.9168_none_HASH\advapi32.dll \Windows\System32\advapi32.dll # HEALTHY: two paths, one file. Explorer bills you for advapi32.dll twice. # BROKEN: only the System32 path listed, and no WinSxS component directory. # That means the component version behind this file is gone. That is store corruption.

Genuine run on a Windows 11 device, build 26200.9168. The component-directory hash is redacted only because it is long, not because it is sensitive.

Never do this: Microsoft's warning is explicit and repeated on three separate documentation pages. "Deleting files from the WinSxS folder or deleting the entire WinSxS folder may severely damage your system so that your PC might not boot and make it impossible to update." Some important system files exist only in WinSxS. The component store also cannot be moved to another volume, because the hard links cannot cross volumes.

The servicing stack: the code that does the work

Microsoft defines the servicing stack as "the component that installs Windows updates", and says it contains the component-based servicing stack, CBS, which is the underlying component for DISM, System File Checker, changing Windows features or roles, and component repair. All four of those things are the same engine wearing different hats.

Here are the binaries. Every path below was confirmed on a live Windows 11 device rather than copied from another article.

BinaryWhere it actually livesWhat it does in the flow
Dism.exeC:\Windows\System32The command line front end. Parses your switches and calls the API.
DismApi.dllC:\Windows\System32The DISM API that Dism.exe and the PowerShell module both call.
DismHost.exeC:\Windows\System32\DismHosts the DISM providers out of process. Several copies during a long run is normal.
dismcore.dll, dismprov.dllC:\Windows\System32\DismThe provider plumbing that DismHost.exe loads.
sfc.exeC:\Windows\System32System File Checker front end. Tiny; the work is in the DLL below.
sfc_os.dllC:\Windows\System32The Windows Resource Protection logic that SFC actually runs.
TrustedInstaller.exeC:\Windows\servicingThe service host. The only thing allowed to modify the store.
CbsApi.dll, CbsMsg.dllC:\Windows\servicingCBS entry points and message resources.
CbsCore.dll, wcp.dllInside WinSxS, not System32The servicing engine and the component platform itself.
poqexec.exeC:\Windows\System32Runs the primitive operations queue at boot, after a reboot-required change.

That row about CbsCore.dll deserves a sentence of its own, because it is the neatest possible demonstration of what WinSxS is for. People expect the servicing engine to be a DLL in System32. It is not. It is a component version inside the store, and the running copy is hard linked out of it.

PowerShell - run elevated
Get-ChildItem C:\Windows\WinSxS -Recurse -Depth 1 -Include CbsCore.dll,wcp.dll -File | Select-Object -ExpandProperty FullName # Finds the servicing engine itself. Note there is no copy in System32. C:\Windows\WinSxS\amd64_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.26100.9156_none_HASH\CbsCore.dll C:\Windows\WinSxS\amd64_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.26100.9156_none_HASH\wcp.dll C:\Windows\WinSxS\x86_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.26100.9156_none_HASH\CbsCore.dll # HEALTHY: at least one servicingstack component directory per architecture, # each containing CbsCore.dll and wcp.dll. # BROKEN: no result at all. The engine that repairs the store is the thing missing, # which is exactly the scenario an out-of-band servicing stack update exists to fix.

Genuine run, with the component hash redacted for width. This is also why Microsoft ships servicing stack updates separately and occasionally out of band: when the repair engine is the broken part, nothing else can repair it.

Gotcha: the two servicing binaries you will most want to check versions on are the two that are not where you expect. TrustedInstaller.exe is in C:\Windows\servicing, not System32, and CbsCore.dll is only inside WinSxS. A detection script that tests Test-Path C:\Windows\System32\CbsCore.dll will report "missing" on every healthy Windows 11 device on earth.

How to verify: read the store before you write to it

Every switch in this section only reads. None of them changes anything. Run all of them before you run anything from the next section.

Step 1: get the real size, not the Explorer size

Microsoft documents one command for this, and its output has eight named fields.

Command Prompt - run as administrator
Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore # Read-only. Produces a report. Changes nothing. Component Store (WinSxS) information: Windows Explorer Reported Size of Component Store : 24.81 GB Actual Size of Component Store : 22.80 GB Shared with Windows : 8.00 GB Backups and Disabled Features : 14.79 GB Cache and Temporary Data : 0 bytes Date of Last Cleanup : 2026-08-16 16:18:49 Number of Reclaimable Packages : 21 Component Store Cleanup Recommended : Yes The operation completed successfully. # HEALTHY: "The operation completed successfully" and Reclaimable Packages at 0. # THIS DEVICE: 21 reclaimable packages and Cleanup Recommended: Yes. # BROKEN: an error before the report, or an Actual Size that never prints.

That is a genuine run on the device I wrote this on, unedited. Now read it the way Microsoft says to read it.

FieldWhat Microsoft says it meansOverhead?
Windows Explorer Reported Size of Component StoreWhat Explorer would compute. Does not factor in hard links inside WinSxS.No, and misleading
Actual Size of Component StoreFactors in hard links inside WinSxS. Does not exclude files shared with Windows.Partly
Shared with WindowsFiles hard linked so they appear both in the store and elsewhere, for the normal operation of Windows.No
Backups and Disabled FeaturesComponents kept to respond to failures in newer components, or to allow enabling more functionality. Includes store metadata and side-by-side components.Yes
Cache and Temporary DataFiles used internally to make servicing operations faster.Yes
Date of Last CleanupDate of the most recently completed component store cleanup.n/a
Number of Reclaimable PackagesSuperseded packages that component cleanup can remove.n/a
Component Store Cleanup RecommendedRecommended when a cleanup may reduce the store overhead.n/a

Microsoft gives an explicit formula for the real overhead: add "Backups and Disabled Features" to "Cache and Temporary Data". Everything else is either shared with running Windows or double-counted.

On my device that arithmetic is 14.79 GB plus 0 bytes, so 14.79 GB of genuine overhead against an apparent 24.81 GB. In Microsoft's own documented example the same arithmetic turns an apparent 4.98 GB into 507.18 MB. Both numbers are real; they measure different things.

Tip: when a user reports that WinSxS is eating their disk, run /AnalyzeComponentStore and quote them the "Shared with Windows" line. On my device that is 8.00 GB of files that are hard linked into running Windows and cannot be freed by any means, because deleting them would delete the live operating system. It ends the conversation faster than any explanation.

Step 2: understand what each /Cleanup-Image switch does

This is where the folklore does real damage, because two of these switches are not reversible. Here is every documented option, with Microsoft's own description.

SwitchDocumented behaviourReversible?
/CheckHealth"Checks whether the image has been flagged as corrupted by a failed process and whether the corruption can be repaired." Reads a flag. Seconds.Read only
/ScanHealth"Scans the image for component store corruption. This operation will take several minutes." Actually walks the store.Read only
/AnalyzeComponentStore"Creates a report of the component store."Read only
/RestoreHealth"Scans the image for component store corruption, and then performs repair operations automatically."Repairs; needs a source
/StartComponentCleanup"Cleans up the superseded components and reduces the size of the component store." Deletes previous versions immediately, with no 30 day grace period and no one-hour timeout.No, but update uninstall still works
/StartComponentCleanup /ResetBase"Removes all superseded versions of every component in the component store." Microsoft warns: "All existing update packages can't be uninstalled after this command is completed, but this won't block the uninstallation of future update packages."No. Permanent.
/SPSupersededRemoves backup files created during a service pack installation. Documented for Windows 10 only. "The service pack cannot be uninstalled after this command is completed."No. Permanent.
/RevertPendingActionsReverts all pending actions from previous servicing operations, to recover from a boot failure. Microsoft: "not supported on a running operating system" and use it "only in a system-recovery scenario on a Windows image that did not boot."Offline only
Destructive: /ResetBase is the switch people paste from forum posts to reclaim disk space. Microsoft is unambiguous that after it completes, every update currently installed becomes permanently non-removable. If a cumulative update later turns out to break a line-of-business application, the documented rollback path is gone from that device. There is no undo, and no registry value that puts it back. Microsoft documents only how to detect that it happened: check LastResetBase_UTC under the Component Based Servicing key.

Step 3: know why CheckHealth and ScanHealth can disagree

This is the single most useful thing in this article, and it comes straight out of the documented wording. /CheckHealth checks whether the image "has been flagged". /ScanHealth "scans the image". Those are different operations, so they can give different answers.

Here is that happening on my device, in one sitting, with nothing changed in between except the scan itself.

Command Prompt - run as administrator
Dism.exe /Online /Cleanup-Image /CheckHealth The component store is repairable. # Reads a flag left by an earlier failed servicing operation. Took about two seconds. Dism.exe /Online /Cleanup-Image /ScanHealth No component store corruption detected. # Actually walked the store. Took several minutes. Found nothing wrong. Dism.exe /Online /Cleanup-Image /CheckHealth No component store corruption detected. # The flag now agrees, because the scan refreshed it. # HEALTHY: "No component store corruption detected." # FLAGGED: "The component store is repairable." Corruption was recorded at some point. # FATAL: "The component store is not repairable." Rebuild or reimage the device.

Genuine sequence, captured in that order. The practical rule falls out of it directly: never act on /CheckHealth alone. Treat it as a cheap hint that a scan is worth the several minutes, not as a verdict.

Gotcha: this cuts the other way too, and that direction is worse. Because /CheckHealth only reads a flag, a device with genuine corruption that has never had a servicing operation fail on it can report "No component store corruption detected" while being thoroughly broken. A monitoring script built on /CheckHealth will report a healthy fleet either way. Only /ScanHealth scans.

Step 4: know what SFC does differently

System File Checker is not a smaller DISM. It works on a different set of files, in a different direction.

sfc /scannowDISM /Cleanup-Image
What it inspectsProtected system files in the live Windows directoriesThe component store itself
Where it repairs fromA cached copy in the component storeWindows Update, or a /Source you supply
Its log%windir%\Logs\CBS\CBS.log, lines tagged [SR]%windir%\Logs\DISM\dism.log, plus CBS.log
Microsoft's framing"a quick check of an online image""a more extensive check that can repair issues with the store"

Row two is the whole reason the folklore order is wrong. SFC repairs live Windows files by copying good versions out of the component store. If the component store is the damaged thing, SFC is copying from the corruption. It will either report that it could not fix some files, or it will succeed and change nothing that mattered.

Microsoft documents four possible SFC outcomes. Learn them, because three of the four are commonly misread as success.

MessageWhat it means
Windows Resource Protection did not find any integrity violations.No protected file was missing or corrupt. This says nothing about the store.
Windows Resource Protection could not perform the requested operation.SFC could not run. Microsoft suggests safe mode and checking that PendingDeletes and PendingRenames exist under %WinDir%\WinSxS\Temp.
Windows Resource Protection found corrupt files and successfully repaired them.Repaired from the store. Review CBS.log for what changed.
Windows Resource Protection found corrupt files but was unable to fix some of them.The strongest signal that the store itself is damaged. Go and fix the store.

Step 5: the log files, and exactly what to grep for

Two logs matter, and Microsoft documents both paths.

Servicing log files - full paths
C:\Windows\Logs\CBS\CBS.log   the servicing engine transcript
C:\Windows\Logs\DISM\dism.log   the DISM front end, default per /LogPath
C:\Windows\Logs\CBS\CbsPersist_<timestamp>.cab   archived CBS logs, rolled automatically
C:\Windows\Logs\DISM\dism.log.bak   archived DISM log, overwritten each roll

Microsoft publishes one exact command for extracting the SFC portion of CBS.log. Use it verbatim.

Command Prompt - run as administrator
findstr /c:"[SR]" %windir%\Logs\CBS\CBS.log >"%userprofile%\Desktop\sfcdetails.txt" # Microsoft's documented extraction. [SR] tags every System File Checker line. # An empty result file means SFC has not run since this log last rolled. findstr /c:"Total Detected Corruption" %windir%\Logs\CBS\CBS.log # The headline counter a store corruption scan writes. This is the number that matters. Total Detected Corruption: 0 CBS Manifest Corruption: 0 CBS Metadata Corruption: 0 CSI Manifest Corruption: 0 CSI Metadata Corruption: 0 CSI Payload Corruption: 0 Total Repaired Corruption: 0 # HEALTHY: every counter reads 0, as above. Genuine output from my device. # BROKEN: Total Detected Corruption is non-zero, and one of the sub-counters names # which layer failed: a manifest, the metadata, or the actual file payload.
Gotcha: do not grep CBS.log for the word "Corruption" and count the hits. Every line in that block contains the word, including the six that read zero. I wrote exactly that bug into the first draft of the companion script, and it cheerfully reported two corruption markers on a device a full scan had just declared clean. Parse the number after the colon, not the presence of the word.

The other line worth knowing is the session marker. Every servicing operation opens and closes one.

PowerShell - run elevated
Select-String -Path C:\Windows\Logs\CBS\CBS.log -Pattern 'Session: .* (initialized by client|finalized)' | Select-Object -Last 4 -ExpandProperty Line # Shows which client asked for servicing, and whether the session closed cleanly. 2026-08-21 23:04:16, Info CBS Session: SESSIONID initialized by client DISM Package Manager Provider 2026-08-21 23:10:48, Info CBS Session: SESSIONID finalized. Reboot required: no [HRESULT = 0x00000000 - S_OK] # HEALTHY: every "initialized" has a matching "finalized" with HRESULT = 0x00000000 - S_OK. # BROKEN: an "initialized" line with no "finalized" partner, or a non-zero HRESULT. # An initialized session with no finalize is a servicing operation that died mid-transaction. # That is precisely what sets the flag /CheckHealth later reads back to you.

Genuine lines with the session identifier redacted. The client name is useful on its own: DISM Package Manager Provider means somebody ran DISM, CbsTask means the scheduled cleanup task, WindowsUpdateAgent means Windows Update.

Step 6: the registry surface

Microsoft documents comparatively little of the servicing registry, so this table separates what is documented from what is merely observable. That distinction matters: an undocumented value can change in any update.

Registry Editor - shared parent key
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing
and, for the repair source policy:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing
Value or subkeyMeaningStatus
LastResetBase_UTCWhen /ResetBase last ran. Microsoft names this value explicitly as the way to determine that.Documented
Policies\Servicing\LocalSourcePathAlternate source path or paths for repair and feature payload, semicolon separated.Documented
Policies\Servicing\UseWindowsUpdateWhether Windows Update may be used as an installation and repair source.Documented
Policies\Servicing\RepairContentServerSourceBacks the "Contact Windows Update directly instead of WSUS" option.Documented
RebootPending subkeyPresent when a servicing change needs a restart to commit.Widely used, not formally documented
Corrupt, AutoRepairNeeded, LifetimeTimesSuccessfullyRepairedPresent on live devices and readable. My device showed Corrupt as 0 and five lifetime successful repairs.Observed, undocumented
TiRunning subkeyPresent while a TrustedInstaller transaction is live.Observed, undocumented
Do not build on the bottom three rows. Corrupt, AutoRepairNeeded, LifetimeTimesSuccessfullyRepaired and TiRunning are things I read off a live device, not things Microsoft publishes. They are interesting for a one-off investigation. Any fleet-wide detection rule built on them can silently invert the day a servicing stack update changes them, and you will not get a deprecation notice.

Step 7: Event Viewer, services and scheduled tasks

Microsoft does not publish an event ID reference table for component-based servicing. Saying so is more useful than inventing one. What it does use is a channel, and the events in it are readable and self-describing.

Event Viewer - Applications and Services Logs › Setup
Channel: Setup   backing file %SystemRoot%\System32\Winevt\Logs\Setup.evtx
Provider: Microsoft-Windows-Servicing
Observed on a live device, message text verbatim:
Id 1   Initiating changes for package KBNNNNNNN. Current state is Staged. Target state is Staged. Client id: CbsTask.
Id 2   Package KBNNNNNNN was successfully changed to the Staged state.
Id 4   A reboot is necessary before package KBNNNNNNN can be changed to the Installed state.

Those three IDs and their exact wording came off my own device, not from a documentation page. Treat them as observed rather than contractual. The reliable reading is the pattern, not the number: an Id 1 that never gets a matching Id 2 for the same KB is a package that started changing state and never arrived.

The service and the task are both documented, and both have a name people get wrong.

ItemNameExpected state
Service, short nameTrustedInstallerManual start. Running only during servicing.
Service, display nameWindows Modules InstallerSame service. This is the name in services.msc.
Scheduled task\Microsoft\Windows\Servicing\StartComponentCleanupReady. Waits at least 30 days after a component update, then removes previous versions.

Microsoft documents two limits on that task that explain a great deal of confusion. Run automatically, it waits at least 30 days after an updated component is installed before uninstalling previous versions. And "if you choose to run this task, the task will have a 1 hour timeout and may not completely clean up all files."

PowerShell - run elevated
Get-ScheduledTask -TaskPath '\Microsoft\Windows\Servicing\' -TaskName StartComponentCleanup | Get-ScheduledTaskInfo | Select-Object LastRunTime, LastTaskResult # Read-only. Tells you whether automatic cleanup is actually completing. LastRunTime LastTaskResult ----------- -------------- 21/08/2026 21:45:23 2147943467 # 2147943467 is 0x8007042B in hex. Genuine reading from my device. # HEALTHY: LastTaskResult 0, and a LastRunTime within the last few weeks. # COMMON: a non-zero result. The documented one-hour timeout means a large store # routinely fails to finish. That explains 21 reclaimable packages sitting there. # BROKEN: task State is Disabled. Microsoft strongly recommends against disabling it.
Context: Microsoft added an explicit note to the cleanup documentation: "Microsoft strongly recommends not disabling component cleanup." The reasoning given is that cleanup is essential for freeing disk space by removing outdated files, and disabling it lets unnecessary files accumulate. If you inherited a build where somebody disabled that task to "stop DISM running at night", that is your growing WinSxS.

You can start the task by hand. Microsoft documents both the console route and the command.

  1. Open Task Scheduler.
  2. Expand the console tree to Task Scheduler Library › Microsoft › Windows › Servicing › StartComponentCleanup.
  3. Under Selected Item, click Run.
  4. Or, from an elevated prompt, run schtasks.exe /Run /TN "\Microsoft\Windows\Servicing\StartComponentCleanup".

Step 8: the PowerShell equivalents

Everything above has a cmdlet. The DISM module ships in the box, so nothing needs installing.

PowerShell - run elevated
# Read only. Same engine as Dism.exe /Online /Cleanup-Image /ScanHealth. Repair-WindowsImage -Online -ScanHealth # Read only. Same as /CheckHealth. Reads the flag, does not scan. Repair-WindowsImage -Online -CheckHealth # REPAIRS. Uses Windows Update unless -Source is given, and -LimitAccess blocks WU. Repair-WindowsImage -Online -RestoreHealth -Source 'D:\sources\sxs' -LimitAccess # Documented -Source behaviour: with several sources, files come from the first # location where they are found and the rest are ignored. Separate them with commas. # With no -Source, "the default location set by Group Policy is used", and # Windows Update is also used for online images. # There is no Repair-WindowsImage switch for /AnalyzeComponentStore. # For the size report you must call Dism.exe. That is a real gap, not an oversight on your part.
Gotcha: Repair-WindowsImage exposes -StartComponentCleanup, -ResetBase and -Defer, so the irreversible cleanup is one flag away in a cmdlet whose name says "repair". Repair-WindowsImage -Online -StartComponentCleanup -ResetBase is exactly as permanent as the DISM command line version, with no extra confirmation prompt. There is no -WhatIf that will save you.

The fix: the correct order, and the source-file problem

The correct order, from Microsoft's own support article

The folklore says SFC then DISM. Microsoft's support article on using System File Checker says the opposite. Its documented steps run DISM.exe /Online /Cleanup-image /Restorehealth first, and only then sfc /scannow.

The reason is the one from the comparison table above. SFC repairs live Windows files by copying known-good versions out of the component store. DISM repairs the component store. Repair the source of truth first, then repair the files that are restored from it. Doing it the other way round asks SFC to fix Windows using a broken reference.

  1. Check for a pending reboot, and reboot if there is one. A servicing change waiting to commit makes every result below unreliable.
  2. Run Dism /Online /Cleanup-Image /AnalyzeComponentStore. Read the real size. Note whether cleanup is recommended.
  3. Run Dism /Online /Cleanup-Image /ScanHealth. This is the scan. Allow several minutes.
  4. If, and only if, the scan reports corruption, run Dism /Online /Cleanup-Image /RestoreHealth. Add /Source and /LimitAccess if Windows Update is not reachable.
  5. Now run sfc /scannow. Let it reach 100 percent before closing the window.
  6. Reboot if either tool asks for one, then re-run /ScanHealth to confirm.
  7. Only after the store is clean, decide separately whether you want /StartComponentCleanup for disk space. Repair and cleanup are different jobs.
Tip: steps 2 and 3 are read-only, and step 5 is where most of the wall-clock time goes. On a fleet, schedule the read-only steps and report on them, then have a human decide about step 4. That is what the companion script for this article does, and it is why it deliberately refuses to run /RestoreHealth at all.

The source-file problem

Now the part that makes /RestoreHealth fail in managed environments. Microsoft documents the default clearly: "Windows Update is the default repair source." The repair source is the same source used for Features on Demand, and it is determined by Group Policy.

So on a device that cannot reach Windows Update, because a proxy blocks it, or because WSUS is enforced, or because the device is offline, /RestoreHealth has nowhere to get known-good files from. It fails with a documented error code.

CodeDocumented symbolDocumented cause
0x800F0906CBS_E_DOWNLOAD_FAILUREThe computer cannot download the required files from Windows Update. Network, proxy, firewall, or a WSUS-only configuration.
0x800F081FCBS_E_SOURCE_MISSINGA source was specified but the path does not contain the required files, the user lacks Read access, or the file set is corrupt, incomplete, or invalid for the running version of Windows.
0x800F0907CBS_E_GROUPPOLICY_DISALLOWEDNo valid alternative source, and the policy is set to never download payload from Windows Update.
0x800F0922CBS_E_INSTALLERS_FAILEDProcessing advanced installers and generic commands failed. Microsoft notes this one is not specific to any feature.

Microsoft documents four kinds of thing you can hand to /Source.

Source typeDocumented example
Mounted Windows imagec:\mount\Windows
Running Windows installation shared on the networkthe shared c:\Windows folder of another machine
Side-by-side folder from media or a sharez:\sources\SxS
WIM file on a share, with an index and a Wim: prefixWim:\\network\images\contoso.wim:3
Command Prompt - run as administrator
Dism /Online /Cleanup-Image /RestoreHealth /Source:c:\test\mount\windows /LimitAccess # Microsoft's documented form for repairing an online image from your own source. # /LimitAccess "Prevents DISM from contacting Windows Update for repair of online images." # Omit /LimitAccess and DISM will still try Windows Update as a backup source. # HEALTHY: "The restore operation completed successfully." # BROKEN: "Error: 0x800f081f The source files could not be found." Your /Source is # wrong, unreadable, or the wrong Windows version. Check %windir%\Logs\DISM\dism.log.
This is the trap that wastes whole afternoons. Microsoft gives two constraints on source media that almost everyone breaks. First: "Only use RTM media regardless of whether the source is a WIM or a mounted Windows image. Refresh media has older file versions excluded from the media and the target operating system may need these files." Second: "Make sure the source is patched to the latest Cumulative Update. If the target OS is patched to a higher level than the source, adding features or repairing Operating Systems may fail because the target OS needs updated files that are not present in the source." A stale ISO from your build share will give you 0x800F081F forever, and the error text will keep insisting the files are not there.

Setting the repair source with Group Policy

Rather than typing /Source on every device, set it once. There is a real GPO for this, and it is the same setting that governs Features on Demand.

Computer ConfigurationAdministrative TemplatesSystemSpecify settings for optional component installation and component repair
  1. Open the Local Group Policy Editor (gpedit.msc) or the Group Policy Management Console.
  2. Expand Computer Configuration, then Administrative Templates, then select System.
  3. Open Specify settings for optional component installation and component repair.
  4. Select Enabled.
  5. In Alternate source file path, enter a fully qualified path. Microsoft's examples are a share such as \\server_name\share\Win8sxs, or a WIM with an index such as WIM:\\server_name\share\install.wim:3. Separate multiple paths with a semicolon.
  6. Optionally tick Never attempt to download payload from Windows Update to block Windows Update entirely. This is the policy equivalent of /LimitAccess.
  7. Optionally tick Contact Windows Update directly to download repair content instead of Windows Server Update Services (WSUS). This is the fix for a WSUS-managed fleet that cannot get repair content.
  8. Click OK, then run gpupdate /force from an elevated prompt.

The policy writes to three values under HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Servicing: LocalSourcePath, UseWindowsUpdate and RepairContentServerSource. Read them to confirm the policy actually landed.

Gotcha: Microsoft states that "Windows Server Update Services (WSUS) is not configurable as a recovery source for Features on Demand." A WSUS-only fleet with no alternate source path and no direct-Windows-Update exception has, by design, no repair source at all. Devices in that state will fail component repair indefinitely, and nothing in the WSUS console will tell you.

Setting the same thing from Intune

The policy is ADMX-backed, so it is reachable from Microsoft Intune. Microsoft documents it in the Policy CSP as ADMX_Servicing/Servicing, mapped to the same friendly name as the GPO.

intune.microsoft.comDevicesConfigurationCreateSettings catalog
  1. Sign in to the Microsoft Intune admin center at intune.microsoft.com.
  2. Go to Devices, then Configuration, then Create, then New policy.
  3. Set Platform to Windows 10 and later and Profile type to Settings catalog. Click Create.
  4. Name the profile, for example Servicing - component repair source. Click Next.
  5. Click Add settings and search the picker for optional component installation.
  6. Select Specify settings for optional component installation and component repair under the Administrative Templates › System category, then close the picker.
  7. Set it to Enabled and fill in the alternate source file path and the two checkboxes exactly as in the GPO steps above.
  8. Click Next through Scope tags, assign to a device group, then Create.

If you would rather use a custom OMA-URI profile, Microsoft documents the path.

Intune custom profile - documented OMA-URI
./Device/Vendor/MSFT/Policy/Config/ADMX_Servicing/Servicing
Data type: String. Scope: Device only, not User.
ADMX file: Servicing.admx   Registry key: Software\Microsoft\Windows\CurrentVersion\Policies\Servicing
Context: this is an ADMX-backed policy, which Microsoft notes "require a special SyncML format to enable or disable" with <Format>chr</Format>. In practice the Settings Catalog handles that encoding for you, which is why the Settings Catalog route above is the one to reach for. The documented applicability is Windows 11 21H2 and later, and Windows 10 2004 and later with KB5005101 installed.

What about Defender, ASR and WDAC?

Genuinely not applicable, and worth saying so rather than padding the article. Component-based servicing has no Defender surface, no attack surface reduction rule, no exploit protection setting, no WDAC policy and no Endpoint Security profile. Store integrity is enforced by Windows Resource Protection and the servicing stack, and the only thing permitted to write to the store is TrustedInstaller. Nothing in the Endpoint Security blade configures any of it. If a vendor tells you their agent "protects WinSxS", ask which documented interface it uses.

Proof it worked: a real read-only store report

The companion script for this article reports component store health without repairing anything. It runs only the two documented read-only DISM reports, /AnalyzeComponentStore and /CheckHealth, then reads the logs, the service, the scheduled task, the documented registry values and the pending-reboot state. It never runs /RestoreHealth, /StartComponentCleanup, /ResetBase or sfc, and it never writes anything.

It needs no PowerShell module. It refuses to run unelevated, because a partial read that looks healthy is worse than no read at all.

PowerShell - run elevated
.\Get-ComponentStoreHealth.ps1 ========================================================================== 1. Real versus apparent store size (Dism /Cleanup-Image /AnalyzeComponentStore) ========================================================================== Explorer reported size : 24.81 GB Actual size : 22.80 GB Shared with Windows : 8.00 GB Backups and disabled features : 14.79 GB Cache and temporary data : 0 bytes Store overhead (documented) : 14.79 GB Date of last cleanup : 2026-08-16 16:18:49 Reclaimable packages : 21 Cleanup recommended (DISM says) : Yes ========================================================================== 2. Corruption flag (Dism /Cleanup-Image /CheckHealth) ========================================================================== Corruption flag : No component store corruption detected # The 10 GB gap between the reported size and the real overhead is the whole point. # 8.00 GB of it is hard linked into running Windows and can never be reclaimed.

Genuine output from the device this article was researched on, with nothing edited except the section spacing. The remaining sections of the same run read as follows.

PowerShell - run elevated
========================================================================== 3. Recent servicing activity (CBS.log) ========================================================================== CBS.log path : C:\WINDOWS\Logs\CBS\CBS.log DISM.log path : C:\WINDOWS\Logs\DISM\dism.log Servicing session lines : 12 Lines marked ", Error " : 0 SFC [SR] lines in window : 0 Total Detected Corruption : 0 Total Repaired Corruption : 0 4. Servicing service and scheduled task Service (display name) : Windows Modules Installer Service status : Running Task state : Ready Task last result : 2147943467 (0x8007042B) 5. Servicing registry surface (documented values) LastResetBase_UTC : absent (ResetBase has never completed on this device) Policies\Servicing\LocalSourcePath: not configured 6. WinSxS structure (context only, not a health verdict) Component directories : 30,125 Manifest files : 43,198 servicing\Packages files : 14,980 Hard links to System32\advapi32.dll: 2 7. Pending reboot state CBS RebootPending : absent PendingFileRenameOperations : PRESENT (2 entries) Summary Reboot pending : YES - PendingFileRenameOperations Store verdict : No corruption flagged Cleanup opportunity : DISM recommends cleanup; 21 reclaimable package(s) # Read this device as: store is clean, 21 superseded packages are reclaimable, # LastResetBase_UTC absent so /ResetBase has never run, and every currently # installed update is therefore still uninstallable. Which is how it should be.

Two things in that output are worth pointing at, because both are the kind of finding a naive script would get wrong.

The LastResetBase_UTC line reports "absent" rather than blank. Absent is a real finding here: it means /ResetBase has never completed on this device, so every installed update is still removable. A script that printed an empty field would leave you unable to tell that apart from a failed read.

And the task last result of 0x8007042B is reported as a fact with its hex form, not as an interpretation. Microsoft does not document what the cleanup task returns on a partial run, so the script says what it read and points at the documented one-hour timeout as the likely explanation. That is the honest version. It is also the version that stays correct after the next servicing stack update.

Reading list from the community

Both of these were fetched and read before being cited here, and both are genuinely on this topic.

AuthorArticleWhy it is worth your time
Rudy OomsIntune Remote Wipe ending up in "Something went wrong" (0x800f0991)?Traces a failure to a single missing payload file inside a WinSxS component directory, with the servicingPackages metadata still present. The best worked example of the mismatch this article describes.
Alok Kumar Mishra, HTMDHow to Analyse and Clean up Component Store WinSxS Folder in Windows 11A clean walkthrough of the analyse and cleanup commands with the Task Scheduler route, if you want the same steps with more screenshots.

References

PowerShell — companion script

Download it from Imran76Awan/Windows-11-Scripts — no sign-in required. It is read-only: it reports and never changes a device or anything in Intune. Validate it in your own environment before relying on the output.

Get-ComponentStoreHealth.ps1 — Reports Windows component store (WinSxS) health and real size WITHOUT repairing anything.
View all scripts on GitHub
Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows 11
The Enablement Package: How 24H2 Becomes 25H2 in a Reboot (and…
Windows 11 24H2 and 25H2 share one servicing branch and one identical set of system…
Windows 11
The WinRE partition is too small: 0x80070643 and the…
A Windows Recovery Environment servicing update fails with 0x80070643 and admins chase…
Windows 11
Servicing Stack Update Before Cumulative Update: Why the Order…
The servicing stack is the code that installs Windows updates, so it has to be current…