Public/Reset-WindowsUpdate.ps1

#requires -Version 2
function Reset-WindowsUpdate
{
    [cmdletbinding(SupportsShouldProcess = $True,ConfirmImpact = 'High')]

    Param(
        [Parameter(Mandatory = $True)]
        [string[]]$ComputerName,
        
        [Parameter(Mandatory = $False)]
        [pscredential]$Credential = $null
    )

    Begin{}

    Process{
        [scriptblock]$Scriptblock = {
            Try
            {
                'bits', 'wuauserv', 'appidsvc', 'cryptsvc' | ForEach-Object -Process {
                    Stop-Service -Name $_ -Force -Confirm:$False -ErrorAction Stop
                }

                Get-ChildItem -Path "$env:ALLUSERSPROFILE\Application Data\Microsoft\Network\Downloader\qmgr*.dat" | Remove-Item -Force -Confirm:$False

                "$env:SystemRoot\SoftwareDistribution", "$env:SystemRoot\system32\catroot2" | 

                ForEach-Object -Process {
                    $Path = $_
                    
                    $NewName = "$(Split-Path -Path $Path -Leaf).bak"
                    
                    Remove-Item -Path "$Path.bak" -Recurse -Force -Confirm:$False -ErrorAction SilentlyContinue

                    Rename-Item -Path $Path -NewName $NewName -Force -Confirm:$False
                }

                Start-Process -FilePath "$env:SystemRoot\System32\sc.exe" -ArgumentList 'sdset bits D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)' -Wait -WindowStyle Hidden

                Start-Process -FilePath "$env:SystemRoot\System32\sc.exe" -ArgumentList 'sdset wuauserv D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)' -Wait -WindowStyle Hidden

                '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-Object -Process {
                    Start-Process -FilePath "$env:SystemRoot\System32\regsvr32.exe" -ArgumentList "/s $_" -Wait -WindowStyle Hidden
                }

                Start-Process -FilePath "$env:SystemRoot\System32\netsh.exe" -ArgumentList 'winsock reset' -Wait -WindowStyle Hidden

                'bits', 'wuauserv', 'appidsvc', 'cryptsvc' | ForEach-Object -Process {
                    Start-Service -Name $_
                }
            }
            Catch
            {
                Write-Warning -Message "$($_.Exception.Message)"
            }
        }

        $InvokeArgs = @{
            ComputerName = $ComputerName
        }
    
        If($null -ne $Credential)
        {
            $InvokeArgs.Credential = $Credential
        }
        
        $InvokeArgs.ComputerName = Test-PSRemoting @InvokeArgs -WarningAction $WarningPreference
        
        If($null -eq $InvokeArgs.ComputerName)
        {
            Break
        }
        
        $InvokeArgs.ScriptBlock = $Scriptblock
        
        If($PSCmdlet.ShouldProcess($ComputerName -join ', '))
        {
            Invoke-Command @InvokeArgs -HideComputerName
        }
    }
    
    End{}
}