Fix your Windows 10 printing problems with this PowerShell script

Windows key on keyboard

If the recent printing problems caused by a string of Windows 10 updates weren't so disruptive -- and if the poor quality of updates from Microsoft hadn't been an issue for so long -- the situation would almost be funny.

As it is, however, those who have been affected by the bug-riddled updates find themselves extraordinarily frustrated and losing trust in Microsoft's ability to deliver reliable software. With so many updates, patches, bug fixes and workarounds having been released in the last couple of weeks, keeping on top of problems has been difficult. This PowerShell script should get things sorted once and for all.

See also:

Advertisement

Tech blogger Günter Born has shared a script written by a reader of his site. Andy has penned a script that completely removes all problematic updates, and should eliminate issues with blue screens and problems with printing that were introduced with this month's updates.

The full text of the script is available below for you to analyze. If you would like to use it, highlight and copy the script, paste it into Notepad and save it with a .ps1 extension.

;@echo off & setlocal & set localfname=%~f0

;Findstr -rbv ; %0 | powershell -c -

;goto:BatchExit

# removes the Windows updates from 03/2021 which cause printer issues

# as of 03/23/2021 'around noon', see also

#   *https://www.borncity.com/blog/2021/03/22/windows-10-mrz-2021-update-erneut-freigegeben/

#

# this batch + powershell script removes various updates based on the

#   name / KB numbers and hides them permanently, 

#   the script needs local administrator rights, it asks for them

#

# if the script has run once and thereby to remove updates were found

#   updates to be removed, then be sure to restart the computer and

#   run the script again directly after the restart, only then the

#   then the last updates to be removed will really

# disappear.

#

# if also after repeated call again and again (the same) Updates

# uninstalled then manually intervene, the Windows Update

# Cache locally delete (Script 02WindowsUpdatesLöschen.cmd), the updates

# manually uninstall the updates and (if at all possible)

# manually hide (with wushowhide.diagcab)

#

# various parts of the script are just mangled and have been

#   shamelessly copied from

#   *ttps://www.powershellmagazine.com/2014/03/19/how-to-view-and-restore-hidden-windows-updates-with-powershell/

# the problematic updates / KB numbers (_without_ the 'KB' label) to be removed and hidden

[email protected]("5000802", "5000808", "5000822", "5000809", "5000812", "5000803", "5000807", "5001567", "5001566", "5001568", "5001565")

Function Main {

    [Cmdletbinding()]

    Param()

    Process {

        # teste ob das Skript als Administrator ausgefuehrt wurde, wenn nicht dann versuche Neustart mit erhoehten Rechten

        CheckAndRaiseElevation

        # test if the script was executed as administrator, if not then try restart with elevated privileges

        If( RemoveWrongHotfixes ) {

            Write-Host "At least one Windows update was found which was uninstalled."

            Write-Host "Please wait, collecting information about pending updates ..."

            Get-WindowsUpdate | Where { $_.Title -match $HotFixesToRemove} | Set-WindowsHiddenUpdate -Hide $True -Verbose

            Write-Host "The previously uninstalled Windows updates have been hidden as far as possible."

            Write-Host "Please restart the computer immediately and run the program right after the start"

            Write-Host "run again."

            Write-Host "n case of an endless loop (if this has already been done several times and this"

            Write-Host "message appears again and again then uninstall and hide"

            Write-Host "perform manually."

            waitkey "Continue with any key, then manually restart [x]" | Out-Null

        } Else {

            # none of the problmatisches updates could be uninstalled anymore, try to find them

            # permanently hide them with the try-and-error method

            Write-Host "Please wait, collect information about pending updates ..."

            Get-WindowsUpdate | Where { $_.Title -match $HotFixesToRemove} | Set-WindowsHiddenUpdate -Hide $True -Verbose

            Write-Host "The previously uninstalled Windows updates have been hidden as far as possible."

            WaitKey "The program can be terminated, continue with any key [x]" | Out-Null

        }

    }

}

Function WaitKey($___text){

    Write-Host $___text

    $___x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null

    Return $___x

}

Function CheckAndRaiseElevation {

    [Cmdletbinding()]

    Param()

    Process {

        # Test if started with enough rights

        $IsElevated=([System.Security.Principal.WindowsPrincipal][System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)

        If( -not $IsElevated ) {

            Write-Host "The program has too few privileges: increased privileges required."

            Try {

                # try to run the batch script again with local administrator rights

                Start-Process -FilePath $env:localfname -Verb RunAs -ErrorAction SilentlyContinue

            }

            Catch {

                Write-Host "The user has refused to increase the privileges - abort!"

                WaitKey "Press any key to end [x]" | Out-Null

            }

            Exit

        }

        # Write-Host "Program is currently running with administrator privileges."

        # change to the original program path if possible, also UNC and mapped network drives possible

        Set-Location $(Split-Path -Parent $env:localfname)

    }

}

# entfernt removes if possible all problematic hotfixes specified as parameters

Function RemoveWrongHotfixes {

    [Cmdletbinding()]

    Param()

    Process {

        $ReturnVal=$False

        $InstalledHotFixes=$(Get-WmiObject -Class win32_quickfixengineering).HotFixID

        Foreach( $InstalledHotFix in $InstalledHotFixes ) {

            Foreach($HotFixToRemove in $HotFixesToRemove) {

                If( $InstalledHotFix -match "$HotFixToRemove") {

                    Write-Host "Das Update $InstalledHotFix wird entfernt"           

                    Start-Process -FilePath "wusa.exe" -Argumentlist "/Uninstall /KB:$HotFixToRemove /quiet /norestart"

                    Write-Host "The update $InstalledHotFix will be hidden permanently"  

                    Get-WindowsUpdate | Where { $_.Title -match "$HotFixToRemove"} | Set-WindowsHiddenUpdate -Hide $true -Verbose

                    $ReturnVal=$true

                }

            }   

        }

        Return $ReturnVal

    }

}

Function Get-WindowsUpdate {

    [Cmdletbinding()]

    Param()

    Process {

        Try {

            Write-Verbose "Query all Windows updates"

            $Session = New-Object -ComObject Microsoft.Update.Session

            $Searcher = $Session.CreateUpdateSearcher()

            $Criteria = "IsInstalled=0 and DeploymentAction='Installation' or IsPresent=1 and DeploymentAction='Uninstallation' or IsInstalled=1 and DeploymentAction='Installation' and RebootRequired=1 or IsInstalled=0 and DeploymentAction='Uninstallation' and RebootRequired=1"

            $SearchResult = $Searcher.Search($Criteria)

            $SearchResult.Updates

        } Catch {

            Write-Warning -Message "Windows update query failed, error $($_.Exception.Message)"

        }

    }

}

# Bonus

Function Show-WindowsUpdate {

    Get-WindowsUpdate |

    Select Title,isHidden,

        @{l='Size (MB)';e={'{0:N2}' -f ($_.MaxDownloadSize/1MB)}},

        @{l='Published';e={$_.LastDeploymentChangeTime}} |

    Sort -Property Published

}

#

# Show-WindowsUpdate

# Show-WindowsUpdate | Where { $_.isHidden }| Out-GridView

Function Set-WindowsHiddenUpdate {

    [Cmdletbinding()]

    Param(

        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]

        [System.__ComObject[]]$Update,

        [Parameter(Mandatory=$true)]

        [boolean]$Hide

    )

    Process {

        $Update | ForEach-Object -Process {

            if ((($_.pstypenames)[0] -eq 'System.__ComObject#{c1c2f21a-d2f4-4902-b5c6-8a081c19a890}') -or

                (($_.pstypenames)[0] -eq 'System.__ComObject#{70cf5c82-8642-42bb-9dbc-0cfd263c6c4f}') -or

                (($_.pstypenames)[0] -eq 'System.__ComObject#{918efd1e-b5d8-4c90-8540-aeb9bdc56f9d}')) {

                try {

                    $_.isHidden = $Hide

                    Write-Verbose -Message "Hide Update $($_.Title) "

                } catch {

                    Write-Warning -Message "Hiding Windows Update failed, error $($_.Exception.Message)"

                }

            } else {

                Write-Warning -Message "Ignore passed object"

            }

        }

    }

}

# Example: hide all open updates

#   Get-WindowsUpdate | Set-WindowsHiddenUpdate -Hide:$true -Verbose

# Example: hide all open definition updates

#   Get-WindowsUpdate | Where { $_.Title -match 'Definitionsupdate' } | Set-WindowsHiddenUpdate -Hide:$false

# Example: hide all open security updates

#   Get-WindowsUpdate | Where { $_.Title -match 'Sicherheitsupdate' } | Set-WindowsHiddenUpdate -Hide:$false

# Example: hide  Browser Choice Updates

#   Get-WindowsUpdate | Where { $_.Title -match 'Microsoft Browser Choice Screen Update'} | Set-WindowsHiddenUpdate -Hide $true -Verbose

main

;:BatchExit

;REM Note: this end of batch script is executed immediately, it does not wait for the end of powershell!

;goto :eof

# Date: 22.03.2021

#

# The errors are / were probably finally fixed with the following updates on 18.03 and 22.03.2021 respectively

# KB5001642 for Windows Server 2008 SP2 x64 (ESU)

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows6.0-kb5001642-x64_4ae1b3c5cebedcd27fe50add6a34e70a00d19b76.msu

# KB5001639 for Windows 7 SP1 x86  (ESU)

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows6.1-kb5001639-x86_f7571200399e9c1099c37cc78c5b0a5481259989.msu

# KB5001639 for Windows 7 SP1 x64  (ESU)

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows6.1-kb5001639-x64_de64f5cb314e3eac59bb3c4371c9ba802adf0f22.msu

# KB5001639 for Windows Server 2008 R2 (ESU)

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows6.1-kb5001639-x64_de64f5cb314e3eac59bb3c4371c9ba802adf0f22.msu

# KB5001641 for Windows Server 2012 x64

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows8-rt-kb5001641-x64_ec0dc33ff8d0d0381eb3fe9595c8a96ccebf9e61.msu

# KB5001640 for Windows 8.1 x86

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows8.1-kb5001640-x86_149741dd2206faf42303dd7a6800567b681367be.msu

# KB5001640 for Windows 8.1 x64

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows8.1-kb5001640-x64_7aa82103f5e37a9d3c2ce2b608c903ed0855ac3b.msu

# KB5001640 for Windows Server 2012 R2

#       http://download.windowsupdate.com/d/msdownload/update/software/updt/2021/03/windows8.1-kb5001640-x64_7aa82103f5e37a9d3c2ce2b608c903ed0855ac3b.msu

# KB5001631 for Windows 10 1507 und Server 2016

# KB5001634 for Windows 10 1803

# KB5001638 for Windows 10 1809 und Server 2019

# KB5001648 for Windows 10 1909

# KB5001649 for Windows 10 2004 und 20H2

#

# buggy so far were the Updates KB5000802, KB5000808, KB5000822, KB5000809, KB5000812, KB5000803, KB5000807, KB5001567, KB5001566, KB5001568, KB5001565

Image credit: Primakov / Shutterstock

© 1998-2021 BetaNews, Inc. All Rights Reserved. Privacy Policy - Cookie Policy.