You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Get-Package返回多结果时,如何循环卸载所有匹配程序?

批量卸载ESET产品的PowerShell脚本问题修正

问题场景

运行PowerShell脚本卸载ESET时,Get-Package返回多个匹配结果,脚本会将多个产品的信息合并成单字符串,导致卸载命令执行失败。现有脚本无法循环处理每个独立的ESET产品。

现有问题代码:

# Uninstall apps
$AppNames = @("eset ")

$AppNames | ForEach-Object {
    $Package = (Get-Package -Name *$_*) | Tee-Object -FilePath $LogPath
    

    if ( $Package.ProviderName -eq "msi" ) {
        $Guid = $Package.FastPackageReference | Tee-Object -FilePath $LogPath -Append
        $Name = $Package.Name | Tee-Object -FilePath $LogPath -Append
        $Version = $Package.Version | Tee-Object -FilePath $LogPath -Append
        "Uninstalling $Name $Version" | Tee-Object -FilePath $LogPath -Append
        $Process = Start-Process msiexec.exe -ArgumentList "/x$Guid /quiet /norestart" -Wait -PassThru
        echo "Exit code: " | Tee-Object -FilePath $LogPath -Append
        $Process | Select ExitCode -ExpandProperty ExitCode | Tee-Object -FilePath $LogPath -Append
    }
}

执行后错误输出示例:

Uninstalling ESET Remote Administrator Agent ESET Endpoint Antivirus 6.5.522.0 10.1.2050.0

问题原因

当Get-Package返回多个对象时,直接访问$Package.ProviderName、$Package.Name等属性会返回所有对象对应属性值组成的数组,字符串拼接时数组元素会自动用空格连接,导致卸载命令中的$Guid也是数组,最终msiexec命令无效。

修正方案

在获取到多个Package对象后,添加一层循环逐个处理每个ESET产品:

# Uninstall apps
$AppNames = @("eset")

$AppNames | ForEach-Object {
    # 获取所有匹配的ESET包,输出到日志
    $Packages = Get-Package -Name *$_* | Tee-Object -FilePath $LogPath
    
    # 循环处理每个单独的Package对象
    $Packages | ForEach-Object {
        $CurrentPackage = $_
        if ($CurrentPackage.ProviderName -eq "msi") {
            $Guid = $CurrentPackage.FastPackageReference 
            $Name = $CurrentPackage.Name 
            $Version = $CurrentPackage.Version 
            
            # 记录当前卸载的产品信息到日志
            "Uninstalling $Name $Version" | Tee-Object -FilePath $LogPath -Append
            "Package GUID: $Guid" | Tee-Object -FilePath $LogPath -Append
            
            # 执行静默卸载命令
            $Process = Start-Process msiexec.exe -ArgumentList "/x$Guid /quiet /norestart" -Wait -PassThru
            
            # 记录卸载退出码
            "Exit code for $Name : $($Process.ExitCode)" | Tee-Object -FilePath $LogPath -Append
        }
    }
}

关键修改点

  • 将$Package改为$Packages,明确表示这是多对象集合
  • 添加$Packages | ForEach-Object {}内部循环,单独处理每个ESET产品包
  • 用$CurrentPackage = $_引用当前单个包对象,避免数组属性拼接问题
  • 优化日志记录逻辑,让每个产品的卸载信息更清晰
  • 简化退出码获取方式,直接通过$Process.ExitCode读取

内容的提问来源于stack exchange,提问作者KLEPTOROTH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:30:15