如何使用PowerShell卸载应用程序?

Rob*_*son 127 windows powershell windows-installer uninstall

有没有一种简单的方法可以使用PowerShell 挂钩标准的" 添加或删除程序 "功能来卸载现有的应用程序?或者检查是否安装了应用程序?

Jef*_*man 150

$app = Get-WmiObject -Class Win32_Product | Where-Object { 
    $_.Name -match "Software Name" 
}

$app.Uninstall()
Run Code Online (Sandbox Code Playgroud)

编辑: Rob发现了另一种使用Filter参数的方法:

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
Run Code Online (Sandbox Code Playgroud)

  • 请注意,查看WMI仅适用于通过MSI安装的产品. (7认同)
  • 经过一些研究后,您还可以使用Get-WmiObject的-filter子句:$ app = Get-WmiObject -Class Win32_Product -filter"select*from Win32_Product WHERE name ='Software Name'" (6认同)
  • 此WMI类需要FOREVER枚举.我建议Jeff更新您的代码以包含Rob的提示. (6认同)
  • `(gwmi Win32_Product | ? Name -eq "Software").uninstall()` 一点代码高尔夫。 (5认同)

nic*_*dnk 49

编辑:多年来,这个答案得到了很多赞成.我想补充一些意见.我从未使用PowerShell,但我记得观察过一些问题:

  1. 如果以下脚本的匹配数多于1,则它不起作用,您必须附加将结果限制为1的PowerShell过滤器.我相信它是-First 1但我不确定.随意编辑.
  2. 如果MSI没有安装该应用程序,则它不起作用.它编写如下的原因是因为它修改MSI以在没有干预的情况下卸载,这在使用本机卸载字符串时并不总是默认情况.

使用WMI对象需要永远.如果您只知道要卸载的程序的名称,则速度非常快.

$uninstall32 = gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
$uninstall64 = gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString

if ($uninstall64) {
$uninstall64 = $uninstall64.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall64 = $uninstall64.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall64 /qb" -Wait}
if ($uninstall32) {
$uninstall32 = $uninstall32.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall32 = $uninstall32.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall32 /qb" -Wait}
Run Code Online (Sandbox Code Playgroud)

  • 我将其转换为带有提示和“我将要卸载的内容”信息的.ps1脚本。https://gist.github.com/chrisfcarroll/e38b9ffcc52fa9d4eb9ab73b13915f5a (3认同)
  • This is gold. Personally, I remove the 'b' from the '/qb' so you don't have to see any dialogs. (2认同)

Rob*_*ner 34

要修复Jeff Hillman的帖子中的第二种方法,你可以做一个:

$app = Get-WmiObject 
            -Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"
Run Code Online (Sandbox Code Playgroud)

要么

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
Run Code Online (Sandbox Code Playgroud)


Dav*_*ler 7

要在这篇文章中添加一些内容,我需要能够从多个服务器中删除软件.我用杰夫的回答引导我:

首先我得到了一个服务器列表,我使用了AD查询,但是你可以提供你想要的计算机名称数组:

$computers = @("computer1", "computer2", "computer3")
Run Code Online (Sandbox Code Playgroud)

然后我循环遍历它们,将-computer参数添加到gwmi查询:

foreach($server in $computers){
    $app = Get-WmiObject -Class Win32_Product -computer $server | Where-Object {
        $_.IdentifyingNumber -match "5A5F312145AE-0252130-432C34-9D89-1"
    }
    $app.Uninstall()
}
Run Code Online (Sandbox Code Playgroud)

我使用IdentifyingNumber属性来匹配而不是名称,只是为了确保我正在卸载正确的应用程序.


Ric*_*rdo 7

我发现不建议使用Win32_Product类,因为它会触发修复并且不会进行查询优化.资源

我发现Sitaram Pamarthi的这篇文章有一个脚本要卸载,如果你知道app guid.他还提供另一个脚本来搜索应用真的很快在这里.

使用如下:.\ uninstall.ps1 -GUID {C9E7751E-88ED-36CF-B610-71A1D262E906}

[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"}
 }
Run Code Online (Sandbox Code Playgroud)


Fra*_*ani 7

一行代码:

get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}
Run Code Online (Sandbox Code Playgroud)


Ehs*_*jad 6

function Uninstall-App {
    Write-Output "Uninstalling $($args[0])"
    foreach($obj in Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") {
        $dname = $obj.GetValue("DisplayName")
        if ($dname -contains $args[0]) {
            $uninstString = $obj.GetValue("UninstallString")
            foreach ($line in $uninstString) {
                $found = $line -match '(\{.+\}).*'
                If ($found) {
                    $appid = $matches[1]
                    Write-Output $appid
                    start-process "msiexec.exe" -arg "/X $appid /qb" -Wait
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样称呼:

Uninstall-App "Autodesk Revit DB Link 2019"
Run Code Online (Sandbox Code Playgroud)