Skip to content
Announcement: We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer.

# Reset Windows Update

Last Updated: 2024-08-07

Info

The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. Developers do have the ability to add custom content, which won't be updated automatically.

Preview Code

    {
      "Content": "Reset Windows Update",
      "category": "Fixes",
      "panel": "1",
      "Order": "a041_",
      "Type": "Button",
      "ButtonWidth": "300",
      "link": "https://christitustech.github.io/winutil/dev/features/Fixes/Update"
    }

## Function: Invoke-WPFFixesUpdate

    function Invoke-WPFFixesUpdate {

        <#

        .SYNOPSIS
            Performs various tasks in an attempt to repair Windows Update

        .DESCRIPTION
            1. (Aggressive Only) Scans the system for corruption using chkdsk, SFC, and DISM
                Steps:
                    1. Runs chkdsk /scan /perf
                        /scan - Runs an online scan on the volume
                        /perf - Uses more system resources to complete a scan as fast as possible
                    2. Runs SFC /scannow
                        /scannow - Scans integrity of all protected system files and repairs files with problems when possible
                    3. Runs DISM /Online /Cleanup-Image /RestoreHealth
                        /Online - Targets the running operating system
                        /Cleanup-Image - Performs cleanup and recovery operations on the image
                        /RestoreHealth - Scans the image for component store corruption and attempts to repair the corruption using Windows Update
                    4. Runs SFC /scannow
                        Ran twice in case DISM repaired SFC
            2. Stops Windows Update Services
            3. Remove the QMGR Data file, which stores BITS jobs
            4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
                DataStore - Contains the Windows Update History and Log Files
                CatRoot2 - Contains the Signatures for Windows Update Packages
            5. Renames the Windows Update Download Folder
            6. Deletes the Windows Update Log
            7. (Aggressive Only) Resets the Security Descriptors on the Windows Update Services
            8. Reregisters the BITS and Windows Update DLLs
            9. Removes the WSUS client settings
            10. Resets WinSock
            11. Gets and deletes all BITS jobs
            12. Sets the startup type of the Windows Update Services then starts them
            13. Forces Windows Update to check for updates

        .PARAMETER Aggressive
            If specified, the script will take additional steps to repair Windows Update that are more dangerous, take a significant amount of time, or are generally unnecessary

        #>

        param($Aggressive = $false)

        Write-Progress -Id 0 -Activity "Repairing Windows Update" -PercentComplete 0
        # Wait for the first progress bar to show, otherwise the second one won't show
        Start-Sleep -Milliseconds 200

        if ($Aggressive) {
            # Scan system for corruption
            Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Scanning for corruption..." -PercentComplete 0
            Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk..." -PercentComplete 0
            # 2>&1 redirects stdout, alowing iteration over the output
            chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
                # Write stdout to the Verbose stream
                Write-Verbose $_

                # Get the index of the total percentage
                $index = $_.IndexOf("Total:")
                if (
                    # If the percent is found
                    ($percent = try {(
                        $_.Substring(
                            $index + 6,
                            $_.IndexOf("%", $index) - $index - 6
                        )
                    ).Trim()} catch {0}) `
                    <# And the current percentage is greater than the previous one #>`
                    -and $percent -gt $oldpercent
                ) {
                    # Update the progress bar
                    $oldpercent = $percent
                    Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
                }
            }

            Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 0
            $oldpercent = 0
            # SFC has a bug when redirected which causes it to output only when the stdout buffer is full, causing the progress bar to move in chunks
            sfc /scannow 2>&1 | ForEach-Object {
                # Write stdout to the Verbose stream
                Write-Verbose $_

                # Filter for lines that contain a percentage that is greater than the previous one
                if (
                    (
                        # Use a different method to get the percentage that accounts for SFC's Unicode output
                        [int]$percent = try {(
                            (
                                $_.Substring(
                                    $_.IndexOf("n") + 2,
                                    $_.IndexOf("%") - $_.IndexOf("n") - 2
                                ).ToCharArray() | Where-Object {$_}
                            ) -join ''
                        ).TrimStart()} catch {0}
                    ) -and $percent -gt $oldpercent
                ) {
                    # Update the progress bar
                    $oldpercent = $percent
                    Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
                }
            }

            Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 0
            $oldpercent = 0
            DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
                # Write stdout to the Verbose stream
                Write-Verbose $_

                # Filter for lines that contain a percentage that is greater than the previous one
                if (
                    ($percent = try {
                        [int]($_ -replace "\[" -replace "=" -replace " " -replace "%" -replace "\]")
                    } catch {0}) `
                    -and $percent -gt $oldpercent
                ) {
                    # Update the progress bar
                    $oldpercent = $percent
                    Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM... ($percent%)" -PercentComplete $percent
                }
            }

            Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC again..." -PercentComplete 0
            $oldpercent = 0
            sfc /scannow 2>&1 | ForEach-Object {
                # Write stdout to the Verbose stream
                Write-Verbose $_

                # Filter for lines that contain a percentage that is greater than the previous one
                if (
                    (
                        [int]$percent = try {(
                            (
                                $_.Substring(
                                    $_.IndexOf("n") + 2,
                                    $_.IndexOf("%") - $_.IndexOf("n") - 2
                                ).ToCharArray() | Where-Object {$_}
                            ) -join ''
                        ).TrimStart()} catch {0}
                    ) -and $percent -gt $oldpercent
                ) {
                    # Update the progress bar
                    $oldpercent = $percent
                    Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
                }
            }
            Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Completed" -PercentComplete 100
        }

        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Stopping Windows Update Services..." -PercentComplete 10
        # Stop the Windows Update Services
        Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping BITS..." -PercentComplete 0
        Stop-Service -Name BITS -Force
        Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping wuauserv..." -PercentComplete 20
        Stop-Service -Name wuauserv -Force
        Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping appidsvc..." -PercentComplete 40
        Stop-Service -Name appidsvc -Force
        Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping cryptsvc..." -PercentComplete 60
        Stop-Service -Name cryptsvc -Force
        Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Completed" -PercentComplete 100

        # Remove the QMGR Data file
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Renaming/Removing Files..." -PercentComplete 20
        Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Removing QMGR Data files..." -PercentComplete 0
        Remove-Item "$env:allusersprofile\Application Data\Microsoft\Network\Downloader\qmgr*.dat" -ErrorAction SilentlyContinue

        if ($Aggressive) {
            # Rename the Windows Update Log and Signature Folders
            Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Renaming the Windows Update Log, Download, and Signature Folder..." -PercentComplete 20
            Rename-Item $env:systemroot\SoftwareDistribution\DataStore DataStore.bak -ErrorAction SilentlyContinue
            Rename-Item $env:systemroot\System32\Catroot2 catroot2.bak -ErrorAction SilentlyContinue
        }

        # Rename the Windows Update Download Folder
        Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Renaming the Windows Update Download Folder..." -PercentComplete 20
        Rename-Item $env:systemroot\SoftwareDistribution\Download Download.bak -ErrorAction SilentlyContinue

        # Delete the legacy Windows Update Log
        Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Removing the old Windows Update log..." -PercentComplete 80
        Remove-Item $env:systemroot\WindowsUpdate.log -ErrorAction SilentlyContinue
        Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Completed" -PercentComplete 100

        if ($Aggressive) {
            # Reset the Security Descriptors on the Windows Update Services
            Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting the WU Service Security Descriptors..." -PercentComplete 25
            Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the BITS Security Descriptor..." -PercentComplete 0
            Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "bits", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)"
            Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the wuauserv Security Descriptor..." -PercentComplete 50
            Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "wuauserv", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)"
            Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Completed" -PercentComplete 100
        }

        # Reregister the BITS and Windows Update DLLs
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Reregistering DLLs..." -PercentComplete 40
        $oldLocation = Get-Location
        Set-Location $env:systemroot\system32
        $i = 0
        $DLLs = @(
            "atl.dll", "urlmon.dll", "mshtml.dll", "shdocvw.dll", "browseui.dll",
            "jscript.dll", "vbscript.dll", "scrrun.dll", "msxml.dll", "msxml3.dll",
            "msxml6.dll", "actxprxy.dll", "softpub.dll", "wintrust.dll", "dssenh.dll",
            "rsaenh.dll", "gpkcsp.dll", "sccbase.dll", "slbcsp.dll", "cryptdlg.dll",
            "oleaut32.dll", "ole32.dll", "shell32.dll", "initpki.dll", "wuapi.dll",
            "wuaueng.dll", "wuaueng1.dll", "wucltui.dll", "wups.dll", "wups2.dll",
            "wuweb.dll", "qmgr.dll", "qmgrprxy.dll", "wucltux.dll", "muweb.dll", "wuwebv.dll"
        )
        foreach ($dll in $DLLs) {
            Write-Progress -Id 5 -ParentId 0 -Activity "Reregistering DLLs" -Status "Registering $dll..." -PercentComplete ($i / $DLLs.Count * 100)
            $i++
            Start-Process -NoNewWindow -FilePath "regsvr32.exe" -ArgumentList "/s", $dll
        }
        Set-Location $oldLocation
        Write-Progress -Id 5 -ParentId 0 -Activity "Reregistering DLLs" -Status "Completed" -PercentComplete 100

        # Remove the WSUS client settings
        if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") {
            Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60
            Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0
            Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError $true
            Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError $true
            Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError $true
            Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100
        }

        # Reset WinSock
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting WinSock..." -PercentComplete 65
        Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Resetting WinSock..." -PercentComplete 0
        Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset" -RedirectStandardOutput $true
        Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy" -RedirectStandardOutput $true
        Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset" -RedirectStandardOutput $true
        Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Completed" -PercentComplete 100

        # Get and delete all BITS jobs
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Deleting BITS jobs..." -PercentComplete 75
        Write-Progress -Id 8 -ParentId 0 -Activity "Deleting BITS jobs" -Status "Deleting BITS jobs..." -PercentComplete 0
        Get-BitsTransfer | Remove-BitsTransfer
        Write-Progress -Id 8 -ParentId 0 -Activity "Deleting BITS jobs" -Status "Completed" -PercentComplete 100

        # Change the startup type of the Windows Update Services and start them
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Starting Windows Update Services..." -PercentComplete 90
        Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting BITS..." -PercentComplete 0
        Get-Service BITS | Set-Service -StartupType Manual -PassThru | Start-Service
        Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting wuauserv..." -PercentComplete 25
        Get-Service wuauserv | Set-Service -StartupType Manual -PassThru | Start-Service
        Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting AppIDSvc..." -PercentComplete 50
        # The AppIDSvc service is protected, so the startup type has to be changed in the registry
        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\AppIDSvc" -Name "Start" -Value "3" # Manual
        Start-Service AppIDSvc
        Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting CryptSvc..." -PercentComplete 75
        Get-Service CryptSvc | Set-Service -StartupType Manual -PassThru | Start-Service
        Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Completed" -PercentComplete 100

        # Force Windows Update to check for updates
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Forcing discovery..." -PercentComplete 95
        Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Forcing discovery..." -PercentComplete 0
        (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
        Start-Process -NoNewWindow -FilePath "wuauclt" -ArgumentList "/resetauthorization", "/detectnow"
        Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Completed" -PercentComplete 100
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Completed" -PercentComplete 100

        $ButtonType = [System.Windows.MessageBoxButton]::OK
        $MessageboxTitle = "Reset Windows Update "
        $Messageboxbody = ("Stock settings loaded.`n Please reboot your computer")
        $MessageIcon = [System.Windows.MessageBoxImage]::Information

        [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
        Write-Host "==============================================="
        Write-Host "-- Reset All Windows Update Settings to Stock -"
        Write-Host "==============================================="

        # Remove the progress bars
        Write-Progress -Id 0 -Activity "Repairing Windows Update" -Completed
        Write-Progress -Id 1 -Activity "Scanning for corruption" -Completed
        Write-Progress -Id 2 -Activity "Stopping Services" -Completed
        Write-Progress -Id 3 -Activity "Renaming/Removing Files" -Completed
        Write-Progress -Id 4 -Activity "Resetting the WU Service Security Descriptors" -Completed
        Write-Progress -Id 5 -Activity "Reregistering DLLs" -Completed
        Write-Progress -Id 6 -Activity "Removing WSUS client settings" -Completed
        Write-Progress -Id 7 -Activity "Resetting WinSock" -Completed
        Write-Progress -Id 8 -Activity "Deleting BITS jobs" -Completed
        Write-Progress -Id 9 -Activity "Starting Windows Update Services" -Completed
        Write-Progress -Id 10 -Activity "Forcing discovery" -Completed
    }

View the JSON file

August 7, 2024