Repair-WindowsComponentStore
Repair the Windows component store. Runs DISM ScanHealth, CheckHealth and RestoreHealth, then sfc /scannow.
needs adminrestart advisedsupports -WhatIfrisk: lowversion 1written by an assistant from cited pages
untested here · 0 fixed, 0 not
Fixes these codes
0x80070570 ERROR_FILE_CORRUPT0x80071A910x80073701 ERROR_SXS_ASSEMBLY_MISSING0x800F0831 CBS_E_STORE_CORRUPTION
What it does
Use this when updates fail because of component store or system file corruption (for example 0x800F0831, 0x80070570, 0x80071A91, 0x80073701).
It runs Microsoft's repair sequence in order:
DISM /Online /Cleanup-Image /ScanHealth looks for corruption
DISM /Online /Cleanup-Image /CheckHealth reports whether corruption was found
DISM /Online /Cleanup-Image /RestoreHealth repairs it, using Windows Update as the source unless you give one
sfc /scannow checks system files against the repaired store
This can take a long time and may look stuck at a percentage. Let it finish. Restart the computer afterwards.
Parameters
-Source: A repair source for DISM, for example WIM:D:\sources\install.wim:1. Used with /RestoreHealth.-LimitAccess: Stops DISM from using Windows Update. Needs -Source.-SkipSfc: Skips the final sfc /scannow.-Restart: Restarts the computer when every step succeeded.
Examples
.\Repair-WindowsComponentStore.ps1 -WhatIf
Shows the steps and changes nothing.
.\Repair-WindowsComponentStore.ps1 -Source 'WIM:D:\sources\install.wim:1' -LimitAccess
Repairs from an install image instead of Windows Update.
Microsoft's guidance
The script
Click the script to select all of it, then copy. Fingerprint of this text (SHA-256): c5e23628bd376c16dcd91198993ce5ba7abeaf290187e08631c13123c866600f. Updated 2026-10-21.
# Copyright (c) 2026 Owen Perry. All rights reserved.
#Requires -Version 5.1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Repairs the Windows component store and system files.
.DESCRIPTION
Use this when updates fail because of component store or system file corruption (for example 0x800F0831, 0x80070570, 0x80071A91, 0x80073701).
It runs Microsoft's repair sequence in order:
DISM /Online /Cleanup-Image /ScanHealth looks for corruption
DISM /Online /Cleanup-Image /CheckHealth reports whether corruption was found
DISM /Online /Cleanup-Image /RestoreHealth repairs it, using Windows Update as the source unless you give one
sfc /scannow checks system files against the repaired store
This can take a long time and may look stuck at a percentage. Let it finish. Restart the computer afterwards.
.PARAMETER Source
A repair source for DISM, for example WIM:D:\sources\install.wim:1. Used with /RestoreHealth.
.PARAMETER LimitAccess
Stops DISM from using Windows Update. Needs -Source.
.PARAMETER SkipSfc
Skips the final sfc /scannow.
.PARAMETER Restart
Restarts the computer when every step succeeded.
.EXAMPLE
.\Repair-WindowsComponentStore.ps1 -WhatIf
Shows the steps and changes nothing.
.EXAMPLE
.\Repair-WindowsComponentStore.ps1 -Source 'WIM:D:\sources\install.wim:1' -LimitAccess
Repairs from an install image instead of Windows Update.
.LINK
https://learn.microsoft.com/en-us/troubleshoot/windows-server/installing-updates-features-roles/error-0x800f0831-installing-update
#>
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param([string]$Source, [switch]$LimitAccess, [switch]$SkipSfc, [switch]$Restart)
$ErrorActionPreference = 'Stop'
if ($LimitAccess -and -not $Source) { throw '-LimitAccess needs -Source.' }
# Keep a log. -WhatIf:$false makes sure it is still written during a -WhatIf run.
$logFolder = Join-Path $env:ProgramData 'Zero-X\logs'
New-Item -ItemType Directory -Path $logFolder -Force -WhatIf:$false | Out-Null
$logging = $false
try {
$logFile = Join-Path $logFolder ('Repair-WindowsComponentStore-{0:yyyyMMdd-HHmmss}.log' -f (Get-Date))
Start-Transcript -Path $logFile -WhatIf:$false | Out-Null
$logging = $true
} catch {
Write-Warning "No log file: $($_.Exception.Message)"
}
$exitCodes = [ordered]@{} # step name -> exit code
try {
foreach ($operation in 'ScanHealth', 'CheckHealth', 'RestoreHealth') {
$dismArgs = @('/Online', '/Cleanup-Image', "/$operation")
if ($operation -eq 'RestoreHealth') {
if ($Source) { $dismArgs += "/Source:$Source" }
if ($LimitAccess) { $dismArgs += '/LimitAccess' }
}
if ($PSCmdlet.ShouldProcess('This computer', "DISM $($dismArgs -join ' ')")) {
Write-Host "DISM $($dismArgs -join ' ')"
& "$env:windir\System32\Dism.exe" @dismArgs
$exitCodes["DISM $operation"] = $LASTEXITCODE
}
}
if (-not $SkipSfc -and $PSCmdlet.ShouldProcess('This computer', 'sfc /scannow')) {
Write-Host 'sfc /scannow'
& "$env:windir\System32\sfc.exe" /scannow
$exitCodes['sfc /scannow'] = $LASTEXITCODE
}
} finally {
if ($logging) { Stop-Transcript | Out-Null }
}
# 0 means the step succeeded. Anything else needs a look at the logs.
$exitCodes.GetEnumerator() | ForEach-Object { '{0,-18} exit code {1}' -f $_.Key, $_.Value }
$problems = @($exitCodes.Values | Where-Object { $_ -ne 0 })
if ($problems.Count -gt 0) {
Write-Warning 'A step reported a problem. Read the log and C:\Windows\Logs\CBS\CBS.log. Do not assume the store is repaired.'
exit 1
}
if ($exitCodes.Count -gt 0) {
Write-Host 'Every step finished with exit code 0. Restart the computer, then try the update again.'
if ($Restart -and $PSCmdlet.ShouldProcess('This computer', 'Restart')) { Restart-Computer -Force }
}