Powershell: Uninstall software on remote computer

by Sitaram Pamarthi on February 20, 2012

Ok. It’s time to uninstall a application using powershell. This post is continuation to Powershell: Script to query softwares installed on remote computer where I discussed about procedure to query installed applications on remote computer without using Win32_Product WMI class. The one advantage with Win32_Product WMI class is it’s uninstall() function using which we can trigger uninstallation of softwares on local or remote computer.

In this post, I am going to provide a powershell script which provides same functionality as uninstall() function of Win32_Product WMI class. My code uses GUID of product to trigger the uninstallation by passing it to msiexec process. It also triggers the uninstallation in silent mode so no UI will appear for the user while performing the uninstallation.

Code goes here…

[cmdletbinding()]            

param (            

 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
 [string]$ComputerName = $env:computername,
 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
 [string]$AppGUID
)            

 try {
  $returnval = ([WMICLASS]"\\$computerName\ROOT\CIMV2:win32_process").Create("msiexec `/x$AppGUID `/norestart `/qn")
 } catch {
  write-error "Failed to trigger the uninstallation. Review the error message"
  $_
  exit
 }
 switch ($($returnval.returnvalue)){
  0 { "Uninstallation command triggered successfully" }
  2 { "You don't have sufficient permissions to trigger the command on $Computer" }
  3 { "You don't have sufficient permissions to trigger the command on $Computer" }
  8 { "An unknown error has occurred" }
  9 { "Path Not Found" }
  9 { "Invalid Parameter"}
 }

Note that you need my previous script(Get-InstalledSoftware.ps1) and the one discussed in this article(Uninstall-InstalledSoftware.ps1) to make this uninstallation works since the code discussed in this article depends on the output of Get-InstalledSoftware.ps1 script.

Usage:

  1. Run Get-InstalledSoftware.ps1 script and note the GUID of application that you want to uninstall.
  2. Run Uninstall-InstalledSoftware.ps1 -GUID <<uninstall application GUID here>>

Uninstall-InstalledSoftware.ps1 -GUID “{54D3F6B5-515B-45B8-8F41-FC4D26FEFFEA}”

Test this script in test environment before you try on any production computer. Any improper use of this script can trigger the uninstallation of multiple applications if handled improperly.

This can made as single liner…..

.\Get-InstalledSoftware.ps1 -ComputerName MyPC1 | ? {$_.AppName -eq “iTunes” } | .\Uninstall-InstalledSoftware.ps1

This triggers the installation of iTunes applications. Please note that at any point of time you are passing the output single computer to Uninstall-InstalledSoftware.ps1.

This is just a initial version. I will enhance it to accept multiple computers and multiple uninstallations at same time. I will also make it more robust to track the uninstallation process.

Hope this helps..

Your comments are welcome

This post was written by...

– who has written 462 posts on Techibee.com.

Sitaram Pamarthi is a windows administrators with 9+ years of experience.read more

{ 19 comments… read them below or add one }

ducu March 22, 2012 at 5:04 pm

Hi Sitaram,

Great work here you have done! I have seen that you posted a way to input a list of computers with the following command Get-Content c:\temp\computers.txt | Get-InstalledSoftware.ps1 but how would you you do do in a single line to extract from a list of computers a specific list of application that would than need to be uninstalled?

Reply

Sitaram Pamarthi March 22, 2012 at 10:51 pm

Ducu,
If I understood your question correctly, you want to scan a list of computers to check if a application is installed or not and the computers list is available in text file.

Assuming I am correct in understanding your requirement, you can do this by using below command.

Get-Content c:\temp\Computers.txt | .\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “iTunes” }

If you want to trigger uninstallation as well, then extend the command like below.

Get-Content c:\temp\Computers.txt | .\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “iTunes” } | .\Uninstall-InstalledSoftware.ps1

PS: I don’t have sophisticated lab to test out these things. So, please try in test bed against few test computers before pushing to production.

Feel free to post questions if any have any.

Reply

ND June 19, 2012 at 3:03 pm

Hi

Uninstall doesn`t work on window 2003/2008 server. It do says uninstalation triggred but doesn`t uninstall the software

ND

Reply

Sitaram Pamarthi June 19, 2012 at 8:38 pm

ND,
Please post the output of get-InstalledSoftware.ps1 output and the command you are using to uninstall the app. That will help me to analyze what went wrong.

Reply

ND June 21, 2012 at 4:19 pm

Get Install Command-

.\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “IBM Parity Client” } -verbose >Getsoft.txt

OutPut -
ComputerName : Computer name
AppName : IBM Parity Client
AppVersion : 2.40.04
AppVendor : IBM
InstalledDate : 20111122
UninstallKey : “C:\Program Files (x86)\InstallShield Installation Information\{4B932CA6-727B-4948-91E3-FFCF75CE3478}\s
etup.exe” -runfromtemp -l0x0009 -removeonly
AppGUID : {4B932CA6-727B-4948-91E3-FFCF75CE3478}

Uninstall command -
.\Get-InstalledSoftware.ps1 | Where {$_.AppName –match “IBM Parity Client” } | .\Uninstall-InstalledSoftware.ps1

OutPut
Uninstallation command triggered successfully

But Program IBM Parity Client doesn`t unistalled.

I had 4 soltwares need uninstall from around 100 boxes.

Thanks

ND

Reply

Sitaram Pamarthi June 21, 2012 at 4:28 pm

Thanks ND. Now I understood the problem. My script is designed to uninstall MSI programs. But in your case, it seems to be a exe installation.

However, you can get this work by changing the below line in Uninstall-InstalledSoftware.ps1…

$returnval = ([WMICLASS]“\\$computerName\ROOT\CIMV2:win32_process”).Create(“msiexec `/x$AppGUID `/qn”)

to…..

$returnval = ([WMICLASS]“\\$computerName\ROOT\CIMV2:win32_process”).Create(“C:\Program Files (x86)\InstallShield Installation Information\{4B932CA6-727B-4948-91E3-FFCF75CE3478}\setup.exe -runfromtemp -l0x0009 -removeonly”)

Try this and let me know how it goes…

Reply

ND June 22, 2012 at 1:26 pm

Hi
Thanks lot, it does help.

I had one more QUS if want uninstall multiple software (preferly one by one) Should I create multiple Uninstall-InstalledSoftware.ps1 files

ND

Reply

Sitaram Pamarthi June 22, 2012 at 4:27 pm

ND, glad to that it is working. No need to create multiple scripts. We can accommodate everything in one place with minor modifications to the code. I will try to do that when I find some time. Email me(http://techibee.com/contact-us) if you are looking for this on urgent basis.

Reply

ATLDrake June 23, 2012 at 12:24 am

Thanks so much for this script, I do have a question though, how would I go about adding filtering, so that I could just pull one program as a -Filter “APPName” parameter? I’m relatively new to Powershell scripting, so any help would be fantastic!

Reply

Sitaram Pamarthi June 23, 2012 at 12:41 am

ATLDrake, you want to filter the output of Get-InstalledSoftware.ps1 by just providing -Filter “iTunes” ? you can pretty much do that. All you need to do is, declare $Filter as [string] type parameter and while adding the AppName object just check if AppName value is equal to the value of $Filter.

Hope that helps..

Reply

ATLDrake June 23, 2012 at 1:02 am

Thanks! I got it to accept the filter and it works, but if I don’t supply an AppName it doesn’t return anything. The simple fix is I have 2 scripts, one that has the filter, one without, but that seems a little silly. I added
“if($AppDisplayName -eq $filter) {”

before

“if(!AppDisplayName){continue} line”

Reply

Steve June 28, 2012 at 2:56 am

I’m fairly new to PowerShell scripting and I love the functionality of this script. I need to be able to use this script to uninstall two apps on our Win7 clients via Altiris. Is the below command correct to look for the app and then delete it from a local computer? I know I’d have to copy the .ps1 files locally, then execute this. Also, can I distribute this in a .bat file?

.\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “%Connect%” } | .\Uninstall-InstalledSoftware.ps1

Thanks!

Reply

Jared Heinrichs June 29, 2012 at 2:12 am

I tried one more variation to the command:

PS C:\powershell> .\Get-InstalledSoftware.ps1 -ComputerName computer01 | ? {$_.AppVendor -eq “Kaseya” } | .\Uninstall-Insta
lledSoftware.ps1

Again it says “Uninstallation command triggered successfully” but the program is never un-installed.

This is being run against a fully patched Windows 7 machine from a fully patched windows 7 machine. I am a domain admin.

Reply

Tam July 18, 2012 at 3:40 pm

Hi There,

Were trying to use this script to uninstall software from around 300 machines in our domain and are testing it in a lab environment.

The results I am getting are that it only seems to run against one server at a time using the following command:

Get-Content .\computers.txt | .\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “My Application” } | .\Uninstall-InstalledSoftware.ps1

From previous threads it was mentioned this technique could be used to not only to retrieve the list of installed software on multiple machines but also to trigger the uninstallation.

Any chance of helping us to find out why this does not move to the next machine? Also have you managed to get any tracing / logging of the uninstall process going, I think this would help me figure out what is going wrong.

Thanks!

Reply

Sitaram Pamarthi July 18, 2012 at 4:03 pm

Tam, The current version of the script in post is not educated to accept multiple things from pipeline. As a workaround, try the below command.

Get-Content .\Computers.txt | .\Get-InstalledSoftware.ps1 | foreach {
.\Uninstall-InstalledSoftware.ps1 -ComputerName $_.ComputerName -AppGUID $_.AppGUID
}

Please test it in lab toughly before trying on production.

Reply

mc July 31, 2012 at 5:24 pm

I just found this yesterday. I was wondering if anyone has modified with “if” statements for OS. Win 7 apps are located here:
“software\wow6432node\microsoft\Windows\currentversion\uninstall”. I was going to play with it this week to try and get it to work for both XP and win 7. But if anyone already has could you post it?

Thanks for all the great work!

Reply

Jonny May 29, 2013 at 7:26 pm

Hi Sitaram,

thanks for the script, its working good, but it will only uninstall from a single server when i try to use get-computers.txt.

If i run this:

Get-Content c:\temp\Computers.txt | .\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “iTunes” } | .\Uninstall-InstalledSoftware.ps1

without the ‘uninstall’ on the end ..then it shows me the software installed on all machines, but when I add the ‘uninstall’ back in ..it only removes the software from a single server?

Do you know what the problem could be?

cheers,
Jon

Reply

Jonny May 29, 2013 at 7:26 pm

Ignore, just read above!

Reply

E5E5 March 2, 2014 at 7:09 pm

Hello,
This is very useful thank you so much!.
I’m trying to install an update to a remote machine with modifying your uninstall script like this…
$product = [WMICLASS]“\\$computerName\ROOT\CIMV2:win32_Product”
$returnval = $product.Install(“msiexec.exe `/update AnUpdate.msp `/qn”)
Although I am member of the Administrators group of the remote machine ; it gives me “You don’t have sufficient permissions to trigger the command “. Do you have any idea to solve it?
Thanks

Reply

Leave a Comment

Previous post:

Next post: