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:
- Run Get-InstalledSoftware.ps1 script and note the GUID of application that you want to uninstall.
- 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
{ 16 comments… read them below or add one }
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?
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.
Hi
Uninstall doesn`t work on window 2003/2008 server. It do says uninstalation triggred but doesn`t uninstall the software
ND
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.
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
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…
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
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.
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!
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..
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”
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!
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.
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!
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.
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!