≡ Menu

PowerShell: Uninstall windows hotfixes(updates)

Are you in need of a script which uninstall patches from both local and remote computers? You landed at right place. Today I came across a question in one of the forum asking for a way to uninstall patches/security updates/hotfixes from llocal or remote computers. While this is an easy thing to perform on local computers, it is little tricky when it comes to remote computers. I thought about it some time and finally came up with below code which works for both local and remote computers. All it does is, constructs a uninstall command for the given patch and executes that using WMI process class.

This script comes handy for you when you want to uninstall patches from Windows 2008 Core server which don’t have a GUI and can’t perform uninstallations the way you do in regular windows 2008 OS.

Here is the code:

function Uninstall-Hotfix {
[cmdletbinding()]
param(
$computername = $env:computername,
[string] $HotfixID
)            

$hotfixes = Get-WmiObject -ComputerName $computername -Class Win32_QuickFixEngineering | select hotfixid            

if($hotfixes -match $hotfixID) {
    $hotfixID = $HotfixID.Replace("KB","")
    Write-host "Found the hotfix KB" + $HotfixID
    Write-Host "Uninstalling the hotfix"
    $UninstallString = "cmd.exe /c wusa.exe /uninstall /KB:$hotfixID /quiet /norestart"
    ([WMICLASS]"\\$computername\ROOT\CIMV2:win32_process").Create($UninstallString) | out-null            

    while (@(Get-Process wusa -computername $computername -ErrorAction SilentlyContinue).Count -ne 0) {
        Start-Sleep 3
        Write-Host "Waiting for update removal to finish ..."
    }
write-host "Completed the uninstallation of $hotfixID"
}
else {            

write-host "Given hotfix($hotfixID) not found"
return
}            

}

Usage:

Uninstall-HotFix -ComputerName PC1 -HotfixID KB123456
{ 31 comments… add one }
  • Tank January 14, 2012, 2:18 am

    I have downloaded the script and tried to run it but get an error:

    Method invocation failed because [System.Management.ManagementClass] doesn’t contain a method named ‘Create’.

    any ideas as to what may be the problem. I am using PrimalScript 2011.

    Thanks
    Tank

    • Sitaram Pamarthi January 16, 2012, 4:19 pm

      Could you please post the total error message here so that I should be able to tell you where it went wrong?

  • Rick February 7, 2012, 8:55 pm

    Here’s the error:

    Method invocation failed because [System.Management.ManagementClass] doesn’t contain a method named ‘Create’.
    At C:\Users\adsmz\documents\Uninstall.ps1:15 char:63
    + ([WMICLASS]”\$computernameROOTCIMV2:win32_process”).Create <<<< ($UninstallString) | out-null
    + CategoryInfo : InvalidOperation: (Create:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

    • Sitaram Pamarthi February 10, 2012, 3:56 pm

      @Rick, @Tank, there is a formatting problem with the code I posted earlier. A few required slashes were missing, hence the error. Please copy the code afresh from the post and given a try again. Let me know if it still fails.

  • Scooter November 10, 2012, 9:58 am

    Works Great!!!!! Thanks, this is very useful

  • John Owens December 19, 2012, 11:26 pm

    Is there a way to point this to an entire OU of computers? Or to read the computer names from a flatfile list?

  • saurabh December 21, 2012, 5:22 pm

    Dude
    i tried this for one server and it resultant in below result and nothing happened on that server. Any idea what is wrong here?

    Found the hotfix KB + 2779030
    Uninstalling the hotfix
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …
    Waiting for update removal to finish …

  • DexterPOSH April 27, 2013, 3:18 am

    Nice , works Great…but I made a change to just filter the KB id while calling the Get-WMiObject itself:
    gwmi win32_quickfixengineering -Filter ‘HotFixId = “KB982665″‘

    this will probably save the hassle to iterate through all collections and improve the performance.

  • James May 20, 2013, 5:31 pm

    Hi I am getting invalid argument errors running this command, not sure whats wrong?

    Get-WmiObject : Cannot validate argument on parameter ‘ComputerName’. The argum
    ent is null or empty. Supply an argument that is not null or empty and then try
    the command again.
    At C:\UNINSTALLER.PS1:8 char:40
    + $hotfixes = Get-WmiObject -ComputerName <<<< $computername -Class Win32_Quic
    kFixEngineering | select hotfixid
    + CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
    ngValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
    Shell.Commands.GetWmiObjectCommand

    Given hotfix(KB2736422) not found

    • James May 20, 2013, 10:54 pm

      Just seen the obvious computername null as I posted this… Apologies it has been a long night 🙂

  • Ashraf September 22, 2013, 5:38 pm

    Hi, newbie here…how to use this script and how to launch it?

    • Sitaram Pamarthi September 24, 2013, 8:23 pm

      Hi Ashraf, you can copy paste the code into a powershell window and press enter till you return to the PS prompt. After that run the below command from the same powershell window.

      Uninstall-HotFix -ComputerName PC1 -HotfixID KB123456

      • praseed April 29, 2015, 11:34 am

        i have saved script as .ps1 file and navigated to directory.After that i have ran the command
        Uninstall-HotFix -ComputerName LIN35000120 -HotfixID KB3006137

        Getting error

        PS C:\temp> Uninstall-HotFix.ps1 -ComputerName LIN35000120 -HotfixID KB3006137
        The term ‘Uninstall-HotFix.ps1’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, ver
        ify that the path is correct and try again.
        At line:1 char:21
        + Uninstall-HotFix.ps1 <<<< -ComputerName LIN35000120 -HotfixID KB3006137
        + CategoryInfo : ObjectNotFound: (Uninstall-HotFix.ps1:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

        • TechiBee April 30, 2015, 8:53 am

          try c:\temp\Uninstall-HotFix.ps1 -ComputerName LIN35000120 -HotfixID KB3006137

          You have either prefix the .\ or need to provide complete path of the script.

  • JP November 22, 2014, 3:42 am

    To uninstall all scripts use:
    $fh = Get-HotFix
    $fh | ForEach-Object -Process {Uninstall-Hotfix -ComputerName . -HotfixID $_.HotFixID}

    Only annoyance is the cmd windows that keep popping up. When I get some time I’ll hide them.

    Thanks.

    • AL January 13, 2015, 8:53 am

      Is there a way to uninstall all installed hotfixes at once? Kind of a noob to scripting so please elaborate a little. I have 30+ installed and would prefer not to have to enter a single line for each KB.

      Thx!

      • TechiBee January 19, 2015, 6:31 am

        I suggest you write a wrapper around this script to uninstall multiple hotfixes.

  • Bainrow February 5, 2015, 6:37 pm

    Thanks a lot! Love this script.

    However I do have one question: Is this script only working for the Windows updates?
    I tested it on Office and .Net hotfixes/updates (Example KB2881083 & KB2978128) which are installed and showing in the update list on my system. However the script keeps returning “Given Hotfix KBxxxxxxx not found.”

  • Rahul June 7, 2015, 6:16 pm

    You are awsome dude. This code saved me half a day 🙂

  • Ken Goist November 19, 2015, 10:53 pm

    I tried the script, and was able to get it to partially work. I received the following error (and I am somewhat new to Powershell)
    Get-Process : Couldn’t connect to remote machine.
    At line:14 char:14
    + while (@(Get-Process wusa -computername $computername -ErrorAction SilentlyC …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Get-Process], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetProcessCommand

    • TechiBee January 4, 2016, 4:59 pm

      is this happening for every computer or a particular computer? Please share more details so that I can dig through the problem.

  • Xiang December 22, 2016, 9:42 pm

    Hello,

    We can replace :
    ([WMICLASS]”\\$computername\ROOT\CIMV2:win32_process”).Create($UninstallString) | out-null
    by:
    Invoke-Expression $UninstallString

    • Xiang December 23, 2016, 3:27 pm

      Hello,

      Sorry, not “Invoke-Expression $UninstallString”, it’s for the local server.
      The correct command is : Invoke-Command -cn $computername {$UninstallString}

      • Wintel Rocks December 23, 2016, 4:39 pm

        True, it works with Invoke-Expression -ComputerName as well but the only catch is remoting should be enabled which is not default in pre-W2012 boxes.

        • Xiang December 27, 2016, 3:02 pm

          Yes, you’re right, I suppose the PsRemoting is enabled on target computer.
          One more thing for Invoke-Command, I forgot to test before posting, there’s an issue to pass the argument with my previous command, the good one is :

          Invoke-Command -cn $computername {cmd.exe /c wusa.exe /uninstall /KB:$Using:hotfixID /quiet /norestart}

          And we can omit the line of $UninstallString declaration.

Leave a Comment