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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/113542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:21:37  来源:igfitidea点击:

How can I uninstall an application using PowerShell?

windowspowershellwindows-installeruninstall

提问by Rob Paterson

Is there a simple way to hook into the standard 'Add or Remove Programs' functionality using PowerShell to uninstall an existing application? Or to check if the application is installed?

是否有一种简单的方法可以使用 PowerShell连接到标准的“添加或删除程序”功能以卸载现有应用程序?或者检查是否安装了应用程序?

回答by Jeff Hillman

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

$app.Uninstall()

Edit:Rob found another way to do it with the Filter parameter:

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

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"

回答by nickdnk

EDIT: Over the years this answer has gotten quite a few upvotes. I would like to add some comments. I have not used PowerShell since, but I remember observing some issues:

编辑:多年来,这个答案得到了很多人的支持。我想补充一些意见。从那以后我就没有使用过 PowerShell,但我记得观察到一些问题:

  1. If there are more matches than 1 for the below script, it does not work and you must append the PowerShell filter that limits results to 1. I believe it's -First 1but I'm not sure. Feel free to edit.
  2. If the application is not installed by MSI it does not work. The reason it was written as below is because it modifies the MSI to uninstall without intervention, which is not always the default case when using the native uninstall string.
  1. 如果以下脚本的匹配项多于 1,则它不起作用,您必须附加将结果限制为 1 的 PowerShell 过滤器。我相信是这样,-First 1但我不确定。随意编辑。
  2. 如果应用程序不是由 MSI 安装的,则它不起作用。它写成如下的原因是因为它修改了 MSI 以在没有干预的情况下卸载,这在使用本机卸载字符串时并不总是默认情况。


Using the WMI object takes forever. This is very fast if you just know the name of the program you want to uninstall.

使用 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}

回答by Robert Wagner

To fix up the second method in Jeff Hillman's post, you could either do a:

要修复 Jeff Hillman 帖子中的第二种方法,您可以执行以下操作:

$app = Get-WmiObject 
            -Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"

Or

或者

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"

回答by David Stetler

To add a little to this post, I needed to be able to remove software from multiple Servers. I used Jeff's answer to lead me to this:

为这篇文章补充一点,我需要能够从多个服务器中删除软件。我用杰夫的回答来引导我:

First I got a list of servers, I used an ADquery, but you can provide the array of computer names however you want:

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

$computers = @("computer1", "computer2", "computer3")

Then I looped through them, adding the -computer parameter to the gwmi query:

然后我遍历它们,将 -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()
}

I used the IdentifyingNumber property to match against instead of name, just to be sure I was uninstalling the correct application.

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

回答by Ricardo

I found out that Win32_Product class is not recommended because it triggers repairs and is not query optimized. Source

我发现不推荐使用 Win32_Product 类,因为它会触发修复并且未进行查询优化。来源

I found this postfrom Sitaram Pamarthi with a script to uninstall if you know the app guid. He also supplies another script to search for apps really fast here.

我发现这篇来自 Sitaram Pamarthi 的帖子有一个脚本,如果你知道应用程序 guid,可以卸载它。他还提供另一个脚本来搜索应用真的很快在这里

Use like this: .\uninstall.ps1 -GUID {C9E7751E-88ED-36CF-B610-71A1D262E906}

像这样使用:.\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"}
 }

回答by Ehsan Iran-Nejad

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
                }
            }
        }
    }
}

Call it this way:

这样称呼它:

Uninstall-App "Autodesk Revit DB Link 2019"

回答by Francesco Mantovani

One line of code:

一行代码:

get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}

回答by Ben Key

I will make my own little contribution. I needed to remove a list of packages from the same computer. This is the script I came up with.

我会做出我自己的一点点贡献。我需要从同一台计算机上删除一个包列表。这是我想出的脚本。

$packages = @("package1", "package2", "package3")
foreach($package in $packages){
  $app = Get-WmiObject -Class Win32_Product | Where-Object {
    $_.Name -match "$package"
  }
  $app.Uninstall()
}

I hope this proves to be useful.

我希望这证明是有用的。

Note that I owe David Stetler the credit for this script since it is based on his.

请注意,我欠 David Stetler 这个脚本的功劳,因为它是基于他的。

回答by RBT

Here is the PowerShell script using msiexec:

这是使用 msiexec 的 PowerShell 脚本:

echo "Getting product code"
$ProductCode = Get-WmiObject win32_product -Filter "Name='Name of my Software in Add Remove Program Window'" | Select-Object -Expand IdentifyingNumber
echo "removing Product"
# Out-Null argument is just for keeping the power shell command window waiting for msiexec command to finish else it moves to execute the next echo command
& msiexec /x $ProductCode | Out-Null
echo "uninstallation finished"

回答by Kolob Canyon

Based on Jeff Hillman's answer:

基于杰夫希尔曼的回答:

Here's a function you can just add to your profile.ps1or define in current PowerShell session:

这是您可以添加到您的profile.ps1或在当前 PowerShell 会话中定义的函数:

# Uninstall a Windows program
function uninstall($programName)
{
    $app = Get-WmiObject -Class Win32_Product -Filter ("Name = '" + $programName + "'")
    if($app -ne $null)
    {
        $app.Uninstall()
    }
    else {
        echo ("Could not find program '" + $programName + "'")
    }
}

Let's say you wanted to uninstall Notepad++. Just type this into PowerShell:

假设您想卸载Notepad++。只需在 PowerShell 中输入:

> uninstall("notepad++")

> uninstall("notepad++")

Just be aware that Get-WmiObjectcan take some time, so be patient!

请注意,这Get-WmiObject可能需要一些时间,所以请耐心等待!