-3

Im new to Powershell and I would like to try to uninstall software with it. I have searched several websites but I cannot find a simple script that allows me to uninstall software on my computer of my choice. Does anyone have a script I could use?

user3929914
  • 151
  • 1
  • 2
  • 11
  • This is really open ended. You can use PowerShell to call WMI, use MSIExec in some cases or whatever uninstall method provided by the software in question. I would not say there is one way to uninstall software _properly_. You could just do this though http://stackoverflow.com/questions/113542/how-can-i-uninstall-an-application-using-powershell – Matt Oct 23 '14 at 12:33
  • Does this answer your question? [How can I uninstall an application using PowerShell?](https://stackoverflow.com/questions/113542/how-can-i-uninstall-an-application-using-powershell) – grepit Sep 16 '22 at 21:31

3 Answers3

0

Take a look at Get-WMIObject -class Win32_Product

There is a method called uninstall

I created a function to search for and remove application

<#
    .SYNOPSIS
        Query WMI for MSI installed applications.

    .DESCRIPTION
        Queries WMI for applications installed by MSI by calling the Win32_Product class,
        all parameters are optional and the -Computer Parameter can be piped to by name only and have multiple entries.

    .PARAMETER  Computername
        Specifies the computer to query, can be an array of computers and can be name piped to.
        Default is localhost.

    .PARAMETER  Software
        Used to search for specific software, e.g *java* or "Java Auto Updater". Wrap strings with Double quotations (").
        Default is "*" wildcard meaning all items.

    .PARAMETER  Uninstall
        Uninstalls all found software using the Uninstall() Method.

    .PARAMETER  Credentials
        This Switch specifies credentials for remote machines. 
        Just using -Credentials will prompt you to enter your credentials when executing the command.

    .PARAMETER Showprogress

        Shows the progress on a per machine basis(works better if you have a few machines to check on).
        Default is off.

    .EXAMPLE
        This will query the local machine for anything installed like "Java" and return it to screen.
        PS C:\> Get-SoftwareNT -Software "*java*"

        This will export all Software installed in the local machine to a file called File.csv With only the Name and installed date selected.
        PS C:\> Get-SoftwareNT | Select-Object -Property name,InstallDate | Export-Csv -Path C:\MyPath\File.csv -NoTypeInformation

        This Searches for software on the computers in the file C:\ListofComputers.txt that match "*Java*" and return it to screen.
        PS C:\> Get-SoftwareNT -Software "*java*" -Computername (Get-Content -Path C:\ListofComputers.txt)

    .EXAMPLE
        This will ask you for your credentials and query the machine BAD-USER and BAD-USER2 for any software that matches the term "*itunes*" and returns it to screen with a progress bar.
        PS C:\> Get-SoftwareNT -Credentials -Computername BAD-USER,BAD-USER2 -Software "*iTunes*" -showprogress

        This will to the same as the command above but then uninstall the software and display a return code
        (0 usually means it was successful, 1603 usually means no permissions)
        PS C:\> Get-SoftwareNT -Credentials -Computername BAD-USER,BAD-USER2 -Software "*iTunes*" -Uninstall

    .NOTES
        Please note that the Win32_Product is quite inefficient as it uses windows installer to query every application installed to gather
        the information and dose a "reconfiguration" in the process, this is bad if you have disabled a service for a msi installed app because in the process it
        dose a repair on the app and if there are any issues it will fix them first and then move on and this means reactivating disabled services etc.


#>

function Get-SoftwareNT {

    [CmdletBinding()] 

        param(

            [Parameter(ValueFromPipelineByPropertyName=$True,ValueFromPipeline=$True)]
            [System.String[]]$Computername = "localhost",

            $Software = "*",

            [Switch]$Uninstall = $false,

            [Switch]$Credentials = $false,

            [Switch]$Showprogress = $false
        )

    BEGIN { 

        $NTErrorLog = "C:\NTErrorLogs\Get-SoftwareNT.txt"
        $Path_Test = Test-Path -Path $NTErrorLog
        $Encoding = "ASCII"

        if (!($Path_Test)) {New-Item -Path (Split-Path $NTErrorLog -Parent) -ItemType Container -ErrorAction SilentlyContinue ; New-Item -Path (Split-Path $NTErrorLog -Parent) -Name (Split-Path $NTErrorLog -Leaf) -ItemType file -Value "Unreachable machines: `n" | Out-Null}
        else {Get-Content -Path $NTErrorLog -Force | Out-File -FilePath ("$NTErrorLog" + '_') -Append -Force -Encoding $Encoding ; Clear-Content $NTErrorLog -Force | Out-Null}

        if ($Credentials) { $credstore = Get-Credential }

        $Count = (100 / ($Computername).Count -as [Decimal])
        [Decimal]$Complete = "0"


        }

    PROCESS{

        Foreach ($Computer in $Computername) {

        try {

            $Computer_Active = $true
            $TestConnection = Test-Connection -Count 1 -ComputerName $Computer -ea Stop

        } catch {

            Write-Warning -Message "$computer was not reachable Logging to $NTErrorLog"
            $Computer | Out-File -FilePath $NTErrorLog -Append -Encoding $Encoding -Force
            $Computer_Active = $false

        }
            if ($Computer_Active) {
                if ($Showprogress) {Write-Progress -Activity "Looking for $Software on $Computer" -CurrentOperation "Connecting to WMI on $Computer" -PercentComplete $Complete}

                if ($Credentials) { $Var1 = Get-WmiObject -Credential $credstore -Class Win32_Product -ComputerName $Computer | Where-Object {$_.name -Like "$Software"} }
                else { $Var1 = Get-WmiObject -Class Win32_Product -ComputerName $Computer | Where-Object {$_.name -Like "$Software"} }

                Write-Output -InputObject $Var1

                if ($Uninstall) { $Var1.Uninstall()  }

                $Complete +=$Count

                }

            if ($Showprogress) {Write-Progress -Activity "Finished with $Computer" -CurrentOperation "Done" -PercentComplete $Complete} 
        }


        if ($Showprogress) {Write-Progress -Activity "Done" -Completed}

    }
    END{}
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I was going to scold you for not citing your source. It appears to be you however http://community.spiceworks.com/scripts/show/2354-get-softwarent-cmdlet-updated – Matt Oct 23 '14 at 13:16
  • Never use Win32_Product. It will force a MSI check every time you query it. http://myitforum.com/cs2/blogs/gramsey/archive/2011/01/25/win32-product-is-evil.aspx – Adam Bertram Oct 23 '14 at 13:37
  • In the .NOTES I mention that it dose that. Not the most efficient way but as a ad-hoc solution it dose the job. There are better ways, this is just one of the ways it can be done. – Nigel Tatschner Oct 23 '14 at 13:46
  • I'd never use that way. Period. Sure, it COULD be done that way but why ever use that method when there are plenty of other ways to get it done that are better? – Adam Bertram Oct 23 '14 at 14:19
0

I created (amongst many other software management functions) a Remove-Software script

that does just what you are asking. However, due to the inherent work of software vendors not sticking with a standard 90% of the time it may need to be tweaked for your situation. This will get you extremely close, if not, all the way.

Adam Bertram
  • 3,858
  • 4
  • 22
  • 28
0

This Scrpts uses Win32_product property to Get the List of Softwares installed on the ws. Then using the Class Key it uninstalls the software.

$classkey = "IdentifyingNumber="$($classKey1.IdentifyingNumber)"",Name=""$($classKey1.Name)"",Version=""$($classKey1.Version)""

The above $class key is modified to suit the form "System.Management.ManagementObject"

                # Load Windows Forms assembly

            [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
            [void][System.Windows.Forms.Application]::EnableVisualStyles()

            # Create a GUI

            $form = New-Object System.Windows.Forms.Form
            $form.text = "Software Uninstall"
            $form.Size = New-Object System.Drawing.Size(920,550)
            $form.BackColor='SkyBlue'
            $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
            $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
            $dataGridView = New-Object System.Windows.Forms.DataGridView
            $dataGridView.Size = New-Object System.Drawing.Size(900,400)
            $dataGridView.DefaultCellStyle.BackColor = 'LightBlue'

            #Button 

            $button = New-Object System.Windows.Forms.Button
            $button.Location = New-Object System.Drawing.Size(400,420)
            $button.Size = New-Object System.Drawing.Size(75,25)
            $button.BackColor = "LightGreen"
            $button.text = "Refresh"
            $form.Controls.Add($button)
            $form.Controls.Add($dataGridView)

            # Note Label
            $Label0 = New-Object System.Windows.Forms.Label
            $Label0.Location = New-Object System.Drawing.Size(15,450)
            $Label0.Size = New-Object System.Drawing.Size(880,50)
            $Label0.Backcolor = [System.Drawing.Color]::Yellow
            $Label0.Font = New-Object System.Drawing.Font("Calibri",14,[System.Drawing.FontStyle]::Bold) 
            $Label0.Text = "Note: This Script Cannot Uninstall Policy Restricted Apps such as McAfee etc. Repair option is not Available in this Version. For Reinstall of Software Kindly use SCCM."
            $form.Controls.Add($Label0) 


            # Select appropriate columns

            $dataGridView.Columns.Insert(0, (New-Object System.Windows.Forms.DataGridViewButtonColumn))
            $dataGridView.ColumnCount = 8
            $dataGridView.ColumnHeadersVisible = $true
            #$dataGridView.HeaderText = "Uninstall"
            $dataGridView.Columns[0].Name = "Uninstall"
            $dataGridView.Columns[1].Name = "Description"
            $dataGridView.Columns[2].Name = "IdentifyingNumber"
            $dataGridView.Columns[3].Name = "Name"
            $dataGridView.Columns[4].Name = "Vendor"
            $dataGridView.Columns[5].Name = "Version"
            $dataGridView.Columns[6].Name = "Caption"
            $dataGridView.Columns[7].Name = "InstallLocation"

            $dataGridView.Columns[0].width = 50
            $dataGridView.Columns[1].width = 200

            # Get a list of items

            Get-WmiObject -Class Win32_Product | foreach {
                $dataGridView.Rows.Add("Uninstall",$_.Description,$_.IdentifyingNumber,$_.Name,$_.Vendor,$_.Version,$_.Caption,$_.InstallLocation) | out-null
            }


            # Refresh

            function gridClick(){
                                    $rowIndex = $dataGridView.CurrentRow.Index
                                    $columnIndex = $dataGridView.CurrentCell.ColumnIndex

                                    If ($columnIndex -eq '0')
                                        {
                                            $columnIndex0 = $dataGridView.ColumnIndex+1
                                            $columnIndex1 = $dataGridView.ColumnIndex+2
                                            $columnIndex2 = $dataGridView.ColumnIndex+3
                                            $columnIndex3 = $dataGridView.ColumnIndex+4
                                            $columnIndex5 = $dataGridView.ColumnIndex+5

                                            $IdentifyingNumber = $dataGridView.Rows[$rowIndex].Cells[$columnIndex1].value
                                            $Name = $dataGridView.Rows[$rowIndex].Cells[$columnIndex0].value
                                            $Version = $dataGridView.Rows[$rowIndex].Cells[$columnIndex5].value

                                            Write-Host $dataGridView.Rows[$rowIndex].Cells[$columnIndex0].value
                                            Write-Host $dataGridView.Rows[$rowIndex].Cells[$columnIndex1].value
                                            Write-Host $dataGridView.Rows[$rowIndex].Cells[$columnIndex5].value


                                            $classKey1 = New-Object PSObject -Property @{
                                                                                            IdentifyingNumber=$IdentifyingNumber
                                                                                            Name=$Name
                                                                                            Version=$Version
                                                                                        }| select IdentifyingNumber, Name, Version

                                            # Write-Host $classKey


                                            $classkey = "IdentifyingNumber=`"$($classKey1.IdentifyingNumber)"",Name=""$($classKey1.Name)"",Version=""$($classKey1.Version)`""


                                            $wshell = New-Object -ComObject Wscript.Shell

                                            $OUTPUT = [System.Windows.Forms.MessageBox]::Show("You Have Selected $Name. Do You Want to Proceed With The Uninstall", "Warning!!!", 4)

                                            if ($OUTPUT -eq "YES" ){       

                                                    Try{

                                                         ([wmi]”\\localhost\root\cimv2:Win32_Product.$classKey”).uninstall()


                                                       }
                                                    Catch{
                                                            Write-Warning $_
                                                         }
                                                }
                                        <#    Else
                                                {
                                                    $wshell = New-Object -ComObject Wscript.Shell

                                                    $wshell.Popup("You Have Selected No, Click Ok to Continue" ,0,"Warning!!!",0x0)
                                                }  
                                        }#>
                                   # Vaid Cell 
                                  <# Else
                                        {   

                                            $wshell = New-Object -ComObject Wscript.Shell

                                            $OUTPUT = $wshell.Popup("You Have Selected Invalid Column. Please click on Uninstall Button" ,0,"Warning!!!",0x0)   
                                        } #>
                                }


            $button.Add_Click({
                $selectedRow = $dataGridView.CurrentRow.Index

                $dataGridView.Rows.Clear()

                start-sleep -s 7

            Get-WmiObject -Class Win32_Product | foreach {
                $dataGridView.Rows.Add("Uninstall",$_.Description,$_.IdentifyingNumber,$_.Name,$_.Vendor,$_.Version,$_.Caption,$_.InstallLocation) | out-null
            }

            })

            $Uninstall = $dataGridView.add_DoubleClick({gridClick})


            # Show the form

            [void]$form.ShowDialog() 
Deep
  • 31
  • 5
  • While answers are always appreciated, it really helps to provide some information about how your code solves the problem at hand. Please provide some context surrounding your answer, and see the [help article](http://stackoverflow.com/help/how-to-answer) for information on how to write great answers. – Obsidian Age Feb 14 '17 at 01:02
  • 1
    Thanks for the feedback... have added the required info – Deep Feb 14 '17 at 07:35