我如何使用PowerShell的卸载应用程序?我如何使用PowerShell的卸载应用程序?(How

2019-06-14 16:16发布

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

Answer 1:

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

$app.Uninstall()

编辑:罗布找到另一种方式与Filter参数做到这一点:

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


Answer 2:

编辑:多年来,这个答案已经得到了相当多的upvotes。 我想补充一些意见。 我还没有使用PowerShell的,因为,但我记得我看到的一些问题:

  1. 如果有超过1场比赛为下面的脚本,它不工作,你必须附加PowerShell的过滤器,限制的结果为1。我认为这是-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}


Answer 3:

要解决起来杰夫·希尔曼后的第二个方法,你既可以做:

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

要么

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


Answer 4:

为了一点点添加到这个帖子,我需要的是能够从多台服务器上删除软件。 我用杰夫的回答使我这个:

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

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

然后,我通过他们循环,加入 - 计算机参数的gwmi查询:

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

我用IdentifyingNumber属性来匹配名称来代替,只是要确定我卸载的正确应用。



Answer 5:

我发现,不建议Win32_Product类,因为它触发维修,不查询优化。 资源

我发现这个职位从Sitaram Pamarthi用一个脚本来卸载,如果你知道应用程序的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"}
 }


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

这样调用它:

Uninstall-App "Autodesk Revit DB Link 2019"


Answer 7:

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

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

我希望这被证明是有用的。

请注意,我欠戴维斯泰特勒的功劳这个脚本,因为它是基于他。



Answer 8:

下面是使用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"


Answer 9:

基于杰夫·希尔曼的答案:

这里是你可以添加到您的函数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 + "'")
    }
}

比方说,你想卸载记事本++ 。 只需键入到PowerShell中:

> uninstall("notepad++")

要知道, Get-WmiObject可能需要一些时间,请耐心等待!



Answer 10:

一行代码:

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


Answer 11:

使用:

function remove-HSsoftware{
[cmdletbinding()]
param(
[parameter(Mandatory=$true,
ValuefromPipeline = $true,
HelpMessage="IdentifyingNumber can be retrieved with `"get-wmiobject -class win32_product`"")]
[ValidatePattern('{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}}')]
[string[]]$ids,
[parameter(Mandatory=$false,
            ValuefromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            HelpMessage="Computer name or IP adress to query via WMI")]
[Alias('hostname,CN,computername')]
[string[]]$computers
)
begin {}
process{
    if($computers -eq $null){
    $computers = Get-ADComputer -Filter * | Select dnshostname |%{$_.dnshostname}
    }
    foreach($computer in $computers){
        foreach($id in $ids){
            write-host "Trying to uninstall sofware with ID ", "$id", "from computer ", "$computer"
            $app = Get-WmiObject -class Win32_Product -Computername "$computer" -Filter "IdentifyingNumber = '$id'"
            $app | Remove-WmiObject

        }
    }
}
end{}}
 remove-hssoftware -ids "{8C299CF3-E529-414E-AKD8-68C23BA4CBE8}","{5A9C53A5-FF48-497D-AB86-1F6418B569B9}","{62092246-CFA2-4452-BEDB-62AC4BCE6C26}"

它不完全测试,但PowerShell的4下运行。

我已经运行,因为它是在这里看到的PS1文件。 让它检索来自所有系统AD ,并试图卸载所有系统上的多个应用程序。

我已经使用了IdentifyingNumber搜索大卫Stetlers输入的软件原因。

未测试:

  1. 不添加IDS在脚本函数的调用,而不是先从参数ID的脚本
  2. 没有自动从函数获取更多然后1个的计算机名称调用脚本
  3. 从管道中检索数据
  4. 使用IP地址连接到系统

什么是不:

  1. 它不提供任何信息,如果该软件实际上是任何给定的系统中找到。
  2. 它不提供有关故障或卸载成功的任何信息。

我无法使用卸载()。 尝试,我得到了一个错误,告诉我,要求具有NULL值的表达式的方法是不可能的。 相反,我用删除-WmiObject可以,这似乎来完成相同的。

注意 :如果没有一台计算机的名字给它去除在Active Directory中的所有系统的软件。



Answer 12:

对于我的大部分程序在这篇文章中的脚本做的工作。 但是,我不得不面对一个传统节目,我不能使用MSIEXEC.EXE或Win32_Product类删除。 (从某种原因,我退出0,但该方案仍然存在)

我的解决方案是使用Win32_Process类:

从帮助nickdnk这个命令是让卸载的exe文件路径:

64位:

[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString

32位:

 [array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString

你将不得不清理结果字符串:

$uninstallPath = $unInstallPathReg[0].UninstallString
$uninstallPath = $uninstallPath -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstallPath = $uninstallPath .Trim()

现在,当你有相关的程序卸载exe文件路径 ,你可以使用这个命令:

$uninstallResult = (Get-WMIObject -List -Verbose | Where-Object {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$unInstallPath")

$ uninstallResult - 将有退出代码。 0成功

上面的命令也可以远程运行 - 我这样做是使用调用命令,但我相信,加入的说法-computername可以工作



文章来源: How can I uninstall an application using PowerShell?