PowerShell Script to uninstall Windows Updates, to fix March 2021 Printing issues

Windows Update[German]Windows March 2021 updates has caused a mess with printing issues (blue screens, graphic printing issues etc.). German blog reader Andy has written a PowerShell script to uninstall the problematic March 2021 updates in Windows 10 that are causing the printing issues reported here on the blog. I’m posting the script here on the blog – perhaps it will be helpful for someone.


Background: March 2021 printing issues

The Windows security updates from March 9, 2021, closed numerous vulnerabilities in the operating system. However, users reported significant printing issues shortly after installing the security updates (and Microsoft has confirmed these issues).

What followed was an update orgy that made many things worse. Above all, the installation of the fix updates was always associated with the risk that something went wrong. In response to my German blog post Windows 7/8.1/Server: Korrektur-Updates für Druckprobleme (März 2021), Andy offered in this comment to provide his generic PowerShell script to clean up the system from the problematic updates for a general use.

PowerShell script for March 2021 update cleanup

I am posting the complete PowerShell script below. It aims to remove all problematic updates from a Windows 10 machine. Note, however, that you use the script at your own risk – I can’t provide support either. Take a look at the script before using it for the first time and modify it if needed.

;@echo off & setlocal & set localfname=%~f0
;Findstr -rbv ; %0 | powershell -c -

# 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
$HotFixesToRemove=@("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

The script is extensively commented (select the source code, copy it to an editor and save it with the extension .ps1). The German edition of the script may be obtained here. At this point my thanks to Andy, and good luck with the update cleanup script.

Similar articles:
Patchday: Windows 10-Updates (March 9, 2021)
Patchday: Updates for Windows 7/Server 2008 R2 (March 9, 2021)
Patchday: Windows 8.1/Server 2012 updates (March 9, 2021)
Windows 10 Updates KB5000802/KB5000808 causes BSOD when printing in win32kfull.sys – pulled?
News about the printer issues (BSOD) after March 2021 update
Microsoft provides workaround for Windows 10 patchday printer issue (BSOD)
Windows 10: Out-of-band Update for Blue Screen printing bug
Windows 10: Still printing issues after update installation (March 2021)
Windows 10: Microsoft confirms graphics printing issues after March 2021 updates
Windows 10: Out-of-band Update for graphics printing bug (March 18, 2021)
Windows 10: Update KB5001649 fails with install error 0x80070541 (March 18, 2021)
Windows 10: Out-of-band Update for graphics printing bug (March 18, 2021)
Windows 10: March 2021 update chaos, rollout stopped again due to new issues?
Windows 10: March 2021 update released again?
Microsoft provides workaround for Windows 10 patchday printer issue (BSOD)
Windows 7/8.1/Server: Out-of-band Updates shall fix printing issues (March 2021)


Cookies helps to fund this blog: Cookie settings

This entry was posted in issue, Update, Windows and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *