Reset-ComponentStorePermission
Reset permissions on the component store. Saves, then resets, the permissions on WinSxS and SoftwareDistribution, and sets TrustedInstaller as the owner of WinSxS.
What it does
Use this only for update errors that mean access denied (0x80070005). It is not a general repair.
It runs the commands from Microsoft's article:
icacls "%windir%\WinSxS" /reset /t /c /q
icacls "%windir%\SoftwareDistribution" /reset /t /c /q
icacls "%windir%\WinSxS" /setowner "NT SERVICE\TrustedInstaller" /t /c /q
This changes permissions on system folders, so the script saves the current permissions first, to %ProgramData%\Zero-X\backup. To undo it, run the restore command the script prints. Restart afterwards and try the update again. It can take several minutes.
Examples
.\Reset-ComponentStorePermission.ps1 -WhatIf
Shows what would happen and changes nothing.
.\Reset-ComponentStorePermission.ps1
Saves the permissions, then resets them.
Microsoft's guidance
The script
Click the script to select all of it, then copy. Fingerprint of this text (SHA-256): 2677c889ca3cf97bec44ccc0a78f794a8c84906d4819ff7d93a806df5332af49. Updated 2026-10-21.
# Copyright (c) 2026 Owen Perry. All rights reserved.
#Requires -Version 5.1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Resets the permissions on the Windows component store and the update download folder.
.DESCRIPTION
Use this only for update errors that mean access denied (0x80070005). It is not a general repair.
It runs the commands from Microsoft's article:
icacls "%windir%\WinSxS" /reset /t /c /q
icacls "%windir%\SoftwareDistribution" /reset /t /c /q
icacls "%windir%\WinSxS" /setowner "NT SERVICE\TrustedInstaller" /t /c /q
This changes permissions on system folders, so the script saves the current permissions first, to %ProgramData%\Zero-X\backup.
To undo it, run the restore command the script prints. Restart afterwards and try the update again. It can take several minutes.
.EXAMPLE
.\Reset-ComponentStorePermission.ps1 -WhatIf
Shows what would happen and changes nothing.
.EXAMPLE
.\Reset-ComponentStorePermission.ps1
Saves the permissions, then resets them.
.LINK
https://learn.microsoft.com/en-us/troubleshoot/windows-client/installing-updates-features-roles/troubleshoot-windows-update-error-0x80070005
#>
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param()
$ErrorActionPreference = 'Stop'
$baseFolder = Join-Path $env:ProgramData 'Zero-X'
$logFolder = Join-Path $baseFolder 'logs'
$backupFolder = Join-Path $baseFolder 'backup'
New-Item -ItemType Directory -Path $logFolder, $backupFolder -Force -WhatIf:$false | Out-Null
$stamp = '{0:yyyyMMdd-HHmmss}' -f (Get-Date)
# Keep a log. -WhatIf:$false makes sure it is still written during a -WhatIf run.
$logging = $false
try {
Start-Transcript -Path (Join-Path $logFolder "Reset-ComponentStorePermission-$stamp.log") -WhatIf:$false | Out-Null
$logging = $true
} catch {
Write-Warning "No log file: $($_.Exception.Message)"
}
$icacls = Join-Path $env:windir 'System32\icacls.exe'
$componentStore = Join-Path $env:windir 'WinSxS'
$dataStore = Join-Path $env:windir 'SoftwareDistribution'
$failed = $false
try {
# Save the current permissions so they can be restored.
foreach ($folder in $componentStore, $dataStore) {
$saveFile = Join-Path $backupFolder ('{0}-permissions-{1}.txt' -f (Split-Path $folder -Leaf), $stamp)
if ($PSCmdlet.ShouldProcess($folder, "Save the current permissions to $saveFile")) {
& $icacls $folder /save $saveFile /t /c /q
Write-Host "To undo: icacls `"$(Split-Path $folder -Parent)`" /restore `"$saveFile`""
}
}
# Reset both folders to the permissions they inherit by default.
foreach ($folder in $componentStore, $dataStore) {
if ($PSCmdlet.ShouldProcess($folder, 'Reset permissions')) {
& $icacls $folder /reset /t /c /q
if ($LASTEXITCODE -ne 0) { $failed = $true; Write-Warning "icacls reset on $folder exited with $LASTEXITCODE" }
}
}
# TrustedInstaller should own the component store.
if ($PSCmdlet.ShouldProcess($componentStore, 'Set the owner to NT SERVICE\TrustedInstaller')) {
& $icacls $componentStore /setowner 'NT SERVICE\TrustedInstaller' /t /c /q
if ($LASTEXITCODE -ne 0) { $failed = $true; Write-Warning "icacls setowner exited with $LASTEXITCODE" }
}
} finally {
if ($logging) { Stop-Transcript | Out-Null }
}
if ($failed) { exit 1 }
if (-not $WhatIfPreference) {
Write-Host 'Done. Restart the computer, then try the update again.'
}