Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何使用PowerShell卸载应用程序?_Windows_Powershell_Windows Installer_Uninstallation - Fatal编程技术网

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

Windows 如何使用PowerShell卸载应用程序?,windows,powershell,windows-installer,uninstallation,Windows,Powershell,Windows Installer,Uninstallation,使用PowerShell卸载现有应用程序时,是否有一种简单的方法连接到标准的“添加或删除程序”功能?或者检查应用程序是否已安装?$app=Get WmiObject-Class Win32_Product | Where Object{ $\u.Name-匹配“软件名称” } $app.Uninstall() 编辑:Rob找到了另一种使用过滤器参数的方法: $app=Get WmiObject-Class Win32\u产品` -过滤器“名称=‘软件名称’” 要解决Jeff Hillman帖子

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

$app=Get WmiObject-Class Win32_Product | Where Object{ $\u.Name-匹配“软件名称” } $app.Uninstall() 编辑:Rob找到了另一种使用过滤器参数的方法:

$app=Get WmiObject-Class Win32\u产品`
-过滤器“名称=‘软件名称’”

要解决Jeff Hillman帖子中的第二种方法,您可以:

$app=获取WmiObject
-查询“从Win32_产品中选择*,其中名称='软件名称'”

$app=Get WmiObject-Class Win32\u产品`
-过滤器“名称=‘软件名称’”

为了给这篇文章增加一点内容,我需要能够从多个服务器上删除软件。我用杰夫的回答来引导我:

首先,我得到了一个服务器列表,我使用了一个查询,但您可以根据需要提供计算机名称数组:

$computers=@(“computer1”、“computer2”、“computer3”)
然后我循环遍历它们,将-computer参数添加到gwmi查询中:

foreach($computers中的服务器){
$app=获取WmiObject-类Win32_产品-计算机$server | Where对象{
$\识别号-匹配“5A5F312145AE-0252130-432C34-9D89-1”
}
$app.Uninstall()
}

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

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

$packages=@(“package1”、“package2”、“package3”)
foreach($package中的package){
$app=获取WmiObject-类Win32_产品| Where对象{
$\u.Name-匹配“$package”
}
$app.Uninstall()
}
我希望这证明是有用的

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

使用:

功能删除HSS软件{
[cmdletbinding()]
param(
[参数(必需=$true,
ValuefromPipeline=$true,
HelpMessage=“IdentificationNumber可以通过`“获取WMIOObject-类win32_产品`”检索]
[验证模式({[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[]]$id,
[参数(强制=$false,
ValuefromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
HelpMessage=“通过WMI查询的计算机名称或IP地址”)]
[别名('hostname,CN,computername')]
[string[]]$computers
)
开始{}
过程{
如果($computers-eq$null){
$computers=Get ADComputer-Filter*|选择dnshostname |%{$\u0.dnshostname}
}
foreach($computers in$computers){
foreach($id中的$id){
写入主机“尝试卸载ID为的软件”、“$ID”、“来自计算机”、“$computer”
$app=Get WmiObject-class Win32_Product-Computername“$computer”-过滤器“identificationnumber=”$id“
$app |删除WmiObject
}
}
}
结束{}
删除HSS软件-ID“{8C299CF3-E529-414E-AKD8-68C23BA4CBE8}”,“{5A9C53A5-FF48-497D-AB86-1F6418B569B9}”,“{62092246-CFA2-4452-BEDB-62AC4BCE6C26}”
它还没有经过全面测试,但它是在PowerShell 4下运行的

我已经运行了PS1文件,如图所示。允许它从中检索所有系统,并尝试卸载所有系统上的多个应用程序

我用识别号搜索了David Stetlers输入的软件原因

未测试:

  • 不向脚本中的函数调用添加ID,而是使用参数ID启动脚本
  • 调用超过1个计算机名的脚本不是从函数中自动检索的
  • 从管道中检索数据
  • 使用IP地址连接到系统
  • 它没有:

  • 它不会提供任何信息,如果该软件实际上是在任何给定的系统上找到的
  • 它不提供任何有关卸载失败或成功的信息
  • 我无法使用卸载()。尝试时,我得到一个错误,告诉我为值为NULL的表达式调用方法是不可能的。相反,我使用了removewmiobject,它似乎实现了同样的功能


    注意事项:如果没有指定计算机名,它将从Active Directory中的所有系统中删除软件。

    我发现不建议使用Win32_产品类,因为它会触发修复,并且未进行查询优化

    我从Sitaram Pamarthi找到了一个脚本,如果您知道应用程序guid,则需要卸载该脚本。他还提供了另一个脚本来快速搜索应用程序

    像这样使用:。\uninstall.ps1-GUID {C9E7751E-88ED-36CF-B610-71A1D262E906}


    编辑:这些年来,这个答案获得了相当多的选票。我想补充一些意见。此后我没有使用过PowerShell,但我记得观察到一些问题:

  • 如果以下脚本的匹配项多于1,则该脚本不起作用,您必须附加PowerShell筛选器以将结果限制为1。我相信是第一个1,但我不确定。请随意编辑
  • 如果应用程序不是由MSI安装的,它将无法工作。按以下方式编写的原因是,它将MSI修改为在不进行干预的情况下卸载,这并不总是使用本机卸载字符串时的默认情况

  • 使用WMI对象需要花费很长时间。如果您只知道要卸载的程序的名称,这将非常快

    $uninstall32=gci“HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall”| foreach{gp$\uw6432node.PSPath}|?{$\匹配“软件名”}选择卸载字符串
    $64
    
    [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"}
     }
    
    # 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 + "'")
        }
    }
    
    [array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString
    
     [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()
    
    $uninstallResult = (Get-WMIObject -List -Verbose | Where-Object {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$unInstallPath")
    
    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"
    
    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"
    
    get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}