Powershell – Trigger uninstall of a Software update on a remote computer

Hello everyone,

 

I did a blog post a few weeks back on how to Force an install of software update in SCCM through WMI with help of Powershell https://timmyit.com/2016/08/01/sccm-and-powershell-force-install-of-software-updates-thats-available-on-client-through-wmi/

For this post i want to focus on how to Uninstall a software update remotely which is fairly simple and does’t involve SCCM at all because, Well SCCM doesn’t have any method for doing that. Regardless if you are using your own WSUS to deploy Windows updates or you have it integrated and using a SUP role in SCCM  or you are just getting them directly from Microsoft the process of uninstalling them are still the same.

 

What do we want to achive ?

Instead of having to go in to the Control panel – Program and Features – Installed Updates and from there right-click and  choose Uninstall we wan’t to automate this task so we could go and have coffee instead or just focus our attention on something more productive. Tho Coffee sounds like a great idea !

 

1

 

The Script

This is a proof of concept and are intended for both people with limited knowledge in powershell or for those who  can modify it for their own needs.


Function Trigger-SUPUninstall
{

Param
(
[String][Parameter(Mandatory=$True, Position=0)] $Computername,
[Int][Parameter(Mandatory=$True, Position=1)] $KBid,
[ValidateSet("Yes","NO")]
[String][Parameter(Mandatory=$False, Position=2)] $ForceRestart
)

Process
{

If ($ForceRestart -eq "Yes")
{
foreach ($Computer in $Computername)
{

Invoke-WmiMethod -computername $Computername -class Win32_Process -Name Create -ArgumentList "cmd /c wusa.exe /quiet /uninstall /KB:$($KBid) /Forcerestart /log:C:\temp\$($KBid)Uninstall.txt" 

}
}

Else
{
foreach ($Computer in $Computername)
{

Invoke-WmiMethod -computername $Computername -class Win32_Process -Name Create -ArgumentList "cmd /c wusa.exe /quiet /uninstall /KB:$($KBid) /norestart /log:C:\temp\$($KBid)Uninstall.txt"
}
}
}
End {}
}

 

 

About the script

 

So we are starting out with 3 parameters

$Computername = Computer name (remote computer you want to run the command on)   $KBid = Software update KB (Knowledge Base) id for example 2887424. Don’t include the KB in the parameter!                                                                                                                                    $ForceRestart = Yes or No and if nothing is specified it will count as No

See examples and the end of the post.

 

Function Trigger-SUPUninstall
{

Param
(
[String][Parameter(Mandatory=$True, Position=0)] $Computername,
[Int][Parameter(Mandatory=$True, Position=1)] $KBName,
[ValidateSet("Yes","NO")]
[String][Parameter(Mandatory=$False, Position=2)] $ForceRestart
)

The rest of the script just runs a Invoke-wmimethod which starts an CMD process with the help of the Win32_Process WMI class and in the ArgumentList parameter we list a CMD command we want to run that in it’s self uninstalls the update with the help of a application called Wusa.exe that’s a part of Windows and lives in the %Windir%\System32 folder.

 

cmd /c wusa.exe /quiet /uninstall /KB:$($KBid) /norestart /log:C:\temp\$($KBid)Uninstall.txt

[/code]

If you wanted to try out the command for your self, just open a command prompt and exclude Variables for KB and LOG (since those variables are for the Powershell script to interpret) like this and input the KB id number.

 

We also put a log file in C:\temp\2887595Uninstall.txt this file it self just contains a bunch of gibberish but it’s a way of seeing that Wusa.exe was launched and makes it easier to troubleshoot if anything seems to be not working properly.

 

wusa.exe /quiet /uninstall /KB:2887595 /norestart /log:C:\temp\2887595Uninstall.txt

 

We do one Invoke-WmiMethod for no restart and one for Force Restart of remote computer depending on what you have specified in the ForceRestart parameter, Yes or No

 

Process
{

If ($ForceRestart -eq "Yes")
{
foreach ($Computer in $Computername)
{

Invoke-WmiMethod -computername $Computername -class Win32_Process -Name Create -ArgumentList "cmd /c wusa.exe /quiet /uninstall /KB:$($KBid) /Forcerestart /log:C:\temp\$($KBid)Uninstall.txt" 

}
}

Else
{
foreach ($Computer in $Computername)
{

Invoke-WmiMethod -computername $Computername -class Win32_Process -Name Create -ArgumentList "cmd /c wusa.exe /quiet /uninstall /KB:$($KBid) /norestart /log:C:\temp\$($KBid)Uninstall.txt"
}
}
}
End {}
}

When running the script you want to see the following ReturnValue 0 which means that the Invoke-Wmimethod was started successfully and after that take a look at the Uninstall log.

4

Just realized when writing this that i haven’t talked about how to check if a remote computer has a specific Software Update or Hotfix which i have to do a blog post on that later on  and last but not least there’s really good reports in SCCM for checking that also.  but as for now you can make due with the following Powershell cmdlet.

 


Get-hotfix -id 2887595 -ComputerName SCCM1

 

Change the -ID parameter to what KB article number you want to search for and then the ComputerName for the remote computer you want to check, the result should look like this if the computer has the Update installed

 

2

 

and if it doesn’t have the Update installed it will prompt a warning like this

 

7

 

Final words

 

Follow the link to get to the documentation on Wusa.exe on MSDN also if you open up a command prompt and write wusa.exe /?  then hit enter you will get information about the switches available for wusa.exe

 

8

9

 

I did experience problems on Windows 10 when using Wusa.exe but that could be because I’m using the RTM version right now and i haven’t investigated it further but it worked fine on Server 2012 R2. I’m going to update my Win10 labs to the latest build and see how it works.

 

Until next time, Cheers Timmy