Reset-WindowsUpdate function

Discussion in 'Scripting' started by GodHand, Jun 5, 2019.

  1. GodHand

    GodHand MDL Senior Member

    Jul 15, 2016
    430
    479
    10
    Works with the latest Windows 10 builds and does not revert custom policy settings set in Group Policy:

    Code:
    Function Reset-WindowsUpdate
    {
    <#
        .SYNOPSIS
            Cleans-up Windows Update distribution folders and resets all dependant services to their default state to mitigate any updaing problems.
       
        .DESCRIPTION
            Stops all Windows Update dependant services, then proceedes to clean all folders used by Windows Update.
            Regenerates the default file structure that Windows requires for proper WSUS service access and authentication.
            Returns all dependant files, security descriptors and permissions back to their default state.
            Resets the local network.
            Restarts all Windows Update dependant services, followed by reauthenticating the device with WSUS servers.
            Optionally, the system will display a progress bar countdown before restarting to futher clear any cache storage.
       
        .EXAMPLE
            PS C:\> Reset-WindowsUpdate
       
        .NOTES
            It is recommended to restart the device after running this function to clear additional system cache reserves.
            Ensure anything of importance is saved or closed before the restart occurs.
    #>
       
        [CmdletBinding()]
        Param ()
       
        Begin
        {
            $VerbosePreference = 'SilentlyContinue'
        }
        Process
        {
            Clear-Host
            Write-Host "Stopping the BITS, wuauserv, AppIDSvc and CryptSvc services..." -NoNewline -ForegroundColor Cyan
            Get-Service -Name BITS, wuauserv, AppIDSvc, CryptSvc -ErrorAction SilentlyContinue | Where-Object -Property Status -EQ Running | Stop-Service -ErrorAction SilentlyContinue
            Clear-DnsClientCache -ErrorAction SilentlyContinue
            Write-Host "[Complete]" -ForegroundColor Cyan
            Write-Host "Resetting Update Containers..." -NoNewline -ForegroundColor Cyan
            Remove-Item -Path "$Env:ALLUSERSPROFILE\Application Data\Microsoft\Network\Downloader\qmgr*.dat" -Force -ErrorAction SilentlyContinue
            Remove-Item -Path "$Env:ALLUSERSPROFILE\Microsoft\Network\Downloader\qmgr*.dat" -Force -ErrorAction SilentlyContinue
            Get-ChildItem -Path $Env:SystemRoot\Logs\WindowsUpdate\* -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
            If (Test-Path -Path $Env:SystemRoot\WinSxS\pending.xml.bak) { Remove-Item -Path $Env:SystemRoot\WinSxS\pending.xml.bak -Force -ErrorAction SilentlyContinue }
            If (Test-Path -Path $Env:SystemRoot\SoftwareDistribution.bak) { Remove-Item -Path $Env:SystemRoot\SoftwareDistribution.bak -Recurse -Force -ErrorAction SilentlyContinue }
            If (Test-Path -Path $Env:SystemRoot\System32\Catroot2.bak) { Remove-Item -Path $Env:SystemRoot\System32\Catroot2.bak -Recurse -Force -ErrorAction SilentlyContinue }
            If (Test-Path -Path $Env:SystemRoot\WindowsUpdate.log.bak) { Remove-Item -Path $Env:SystemRoot\WindowsUpdate.log.bak -Force -ErrorAction SilentlyContinue }
            If (Test-Path -Path $Env:SystemRoot\WinSxS\pending.xml)
            {
                Start-Process -FilePath TAKEOWN -ArgumentList ("/F $Env:SystemRoot\WinSxS\pending.xml") -WindowStyle Hidden -Wait
                Start-Process -FilePath ATTRIB -ArgumentList ("-R -S -H /S /D $Env:SystemRoot\WinSxS\pending.xml") -WindowStyle Hidden -Wait
                Rename-Item -Path $Env:SystemRoot\WinSxS\pending.xml -NewName pending.xml.bak -Force -ErrorAction SilentlyContinue
            }
            If (Test-Path -Path $Env:SystemRoot\SoftwareDistribution)
            {
                Start-Process -FilePath ATTRIB -ArgumentList ("-R -S -H /S /D $Env:SystemRoot\SoftwareDistribution") -WindowStyle Hidden -Wait
                Rename-Item -Path $Env:SystemRoot\SoftwareDistribution -NewName SoftwareDistribution.bak -Force -ErrorAction SilentlyContinue
                If (Test-Path -Path $Env:SystemRoot\SoftwareDistribution) { Write-Warning "Failed to reset the Software Distribution folder."; Break }
            }
            If (Test-Path -Path $Env:SystemRoot\System32\Catroot2)
            {
                Start-Process -FilePath ATTRIB -ArgumentList ("-R -S -H /S /D $Env:SystemRoot\System32\Catroot2") -WindowStyle Hidden -Wait
                Rename-Item -Path $Env:SystemRoot\System32\Catroot2 -NewName Catroot2.bak -Force -ErrorAction SilentlyContinue
            }
            If (Test-Path -Path $Env:SystemRoot\WindowsUpdate.log)
            {
                Start-Process -FilePath ATTRIB -ArgumentList ("-R -S -H /S /D $Env:SystemRoot\WindowsUpdate.log") -WindowStyle Hidden -Wait
                Rename-Item -Path $Env:SystemRoot\WindowsUpdate.log -NewName WindowsUpdate.log.bak -Force -ErrorAction SilentlyContinue
            }
            Write-Host "[Complete]" -ForegroundColor Cyan
            Write-Host "Resetting Service Security Descriptors..." -NoNewline -ForegroundColor Cyan
            Start-Process -FilePath CMD -ArgumentList ("/C `"SC.EXE SDSET wuauserv D:(A;;CCLCSWLOCRRC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLCRSDRCWDWO;;;SO)(A;;CCLCSWRPWPDTLOCRRC;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;WD)`"") -WindowStyle Hidden -Wait
            Start-Process -FilePath CMD -ArgumentList ("/C `"SC.EXE SDSET BITS D:(A;;CCLCSWLOCRRC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLCRSDRCWDWO;;;SO)(A;;CCLCSWRPWPDTLOCRRC;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;WD)`"") -WindowStyle Hidden -Wait
            Start-Process -FilePath CMD -ArgumentList ("/C `"SC.EXE SDSET CryptSvc D:(A;;CCLCSWLOCRRC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLCRSDRCWDWO;;;SO)(A;;CCLCSWRPWPDTLOCRRC;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;WD)`"") -WindowStyle Hidden -Wait
            Start-Process -FilePath CMD -ArgumentList ("/C `"SC.EXE SDSET TrustedInstaller D:(A;;CCLCSWLOCRRC;;;AU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLCRSDRCWDWO;;;SO)(A;;CCLCSWRPWPDTLOCRRC;;;SY)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;WD)`"") -WindowStyle Hidden -Wait
            Write-Host "[Complete]" -ForegroundColor Cyan
            Write-Host "Re-registering Update Modules..." -NoNewline -ForegroundColor Cyan
            Set-Location -Path "$Env:SystemRoot\System32"
            @('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', 'wudriver.dll') | ForEach-Object { Start-Process -FilePath REGSVR32 -ArgumentList ("/S $($_)") -WindowStyle Hidden -Wait }
            Start-Process -FilePath NETSH -ArgumentList ('WINSOCK RESET') -WindowStyle Hidden -Wait
            Start-Process -FilePath NETSH -ArgumentList ('WINHTTP RESET PROXY') -WindowStyle Hidden -Wait
            Get-BitsTransfer -ErrorAction SilentlyContinue | Remove-BitsTransfer -ErrorAction SilentlyContinue
            Write-Host "[Complete]" -ForegroundColor Cyan
            Write-Host "Restarting the BITS, wuauserv, AppIDSvc, CryptSvc, DcomLaunch and TrustedInstaller services..." -NoNewline -ForegroundColor Cyan
            Get-Service -Name BITS, wuauserv, AppIDSvc, CryptSvc, DcomLaunch, TrustedInstaller -ErrorAction SilentlyContinue | Set-Service -StartupType Automatic -ErrorAction SilentlyContinue
            Get-Service -Name BITS, wuauserv, AppIDSvc, CryptSvc -ErrorAction SilentlyContinue | Where-Object -Property Status -EQ Stopped | Start-Service -ErrorAction SilentlyContinue
            Write-Host "[Complete]" -ForegroundColor Cyan
        }
    }
    You can simply copy this entire function, and paste it in PowerShell ISE and run it with Reset-WindowsUpdate, or add it to any personal PowerShell module you have so you can run it from anywhere at any time.
     
  2. pf100

    pf100 MDL Expert

    Oct 22, 2010
    1,589
    2,262
    60
    Works great. Thanks.