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

有没有简单的方法来钩入标准的“ 添加或删除程序 ”function使用PowerShell 卸载现有的应用程序 ? 或者检查应用程序是否安装?

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

编辑:罗布find了另一种方法来做到这一点与Filter参数:

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

为了解决Jeff Hillman的文章中的第二种方法,你可以做一个:

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

要么

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

编辑:多年来,这个答案已经得到了不lessupvotes。 我想补充一些意见。 我没有使用PowerShell,但我记得有一些问题:

  1. 如果在下面的脚本中有比1更多的匹配项,它不起作用,您必须附加PowerShell筛选器,将结果限制为1.我相信这是-First 1但我不确定。 随意编辑。
  2. 如果应用程序不是由MSI安装,则不起作用。 之所以如此编写,是因为它修改了MSI以便在没有干预的情况下进行卸载,当使用本机卸载string时,这并不总是默认的情况。

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

要添加一些这个职位,我需要能够从多个服务器中删除软件。 我用杰夫的答案来引导我:

首先,我得到了一个服务器列表,我使用了一个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属性来匹配而不是名称,只是为了确保我正在卸载正确的应用程序。

我发现不build议使用Win32_Product类,因为它会触发修复,而不是查询优化。 资源

我发现这个post从Sitaram Pamarthi脚本卸载,如果你知道应用程序的GUID。 他还提供了另一个脚本来在这里快速search应用程序。

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

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

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

我希望这certificate是有用的。

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

基于Jeff Hillman的回答:

这里有一个函数可以添加到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 + "'") } } 

假设您想卸载Notepad ++ 。 只需在PowerShell中input以下内容:

> uninstall("notepad++")

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

使用:

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

它没有完全testing,但它运行在PowerShell 4下。

我已经在这里看到了PS1文件。 让它从AD中检索所有系统,并尝试卸载所有系统上的多个应用程序。

我使用了IdentifyingNumber来searchDavid Stetlersinput的软件原因。

未testing:

  1. 不要在脚本中调用函数,而是使用参数ID启动脚本
  2. 使用多于1个计算机名称调用脚本, 而不是从函数中自动检索
  3. 从pipe道中检索数据
  4. 使用IP地址连接到系统

它不是:

  1. 它没有给出任何信息,如果软件实际上是在任何给定的系统上find的。
  2. 它没有提供有关卸载失败或成功的任何信息。

我无法使用卸载()。 试着,我得到一个错误告诉我,调用一个值为NULL的expression式的方法是不可能的。 相反,我用Remove-WmiObject,这似乎完成相同。

小心 :如果没有计算机名称,则会从Active Directory中的所有系统中删除该软件。

对于我的大部分程序来说,本文中的脚本完成了这项工作。 但是我不得不面对一个遗留的程序,我无法使用msiexec.exe或Win32_Product类删除。 (由于某种原因,我得到0号出口,但程序仍然在那里)

我的解决scheme是使用Win32_Process类:

在nickdnk的帮助下,这个命令是得到卸载exe文件的path:

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 

你将不得不清理结果string:

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

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

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

$ uninstallResult – 将有退出代码。 0是成功的

上述命令也可以远程运行 – 我使用invoke命令做到了,但我相信添加参数-computername可以工作

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