我试图得到一组应用程序的卸载路径并卸载它们。到目前为止,我可以得到卸载路径的列表。但我很难真正卸载这些程序。
到目前为止,我的代码是。
$app = @("msi1", "msi2", "msi3", "msi4")
$Regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
foreach ($apps in $app){
$UninstallPath = Get-ItemProperty $Regpath | where {$_.displayname -like "*$apps*"} | Select-Object -Property UninstallString
$UninstallPath.UninstallString
#Invoke-Expression UninstallPath.UninstallString
#start-process "msiexec.exe" -arg "X $UnistallPath /qb" - wait
}
这将返回以下结果:
MsiExec.exe /X{F17025FB-0401-47C9-9E34-267FBC619AAE}
MsiExec.exe /X{20DC0ED0-EA01-44AB-A922-BD9932AC5F2C}
MsiExec.exe /X{29376A2B-2D9A-43DB-A28D-EF5C02722AD9}
MsiExec.exe /X{18C9B6D0-DCDC-44D8-9294-0ED24B080F0C}
我正在努力寻找执行这些卸载路径,并实际卸载MSI。
我试过使用Invoke-Expression $UninstallPath.UninstallString
,但它只显示windows安装程序,并给我msiexec的选项。
我也试过使用start-process "msiexec.exe" -arg "X $UnistallPath /qb" - wait
,但这给出了同样的问题。
2条答案
按热度按时间abithluo1#
注:
PackageManagement
模块的Get-Package
和**Uninstall-Package
**cmdlet避免了原来的问题。Uninstall-Package
支持卸载MSI安装的软件(-ProviderName msi
),但似乎 * 不 *“程序”(-ProviderName Programs
);我不清楚是否支持卸载 Windows Update 软件包(-ProviderName msu
)。但是,请注意,这些提供程序仅(直接)在 Windows PowerShell[1]中可用-相比之下,PowerShell (Core)从v7.3.3开始完全缺少这些包提供程序,并且(对我来说)不清楚是否会添加它们。
问题:
UninstallString
/QuietUninstallString
注册表值[2]中的卸载命令行是为来自-*cmd.exe
* 的 no-shell /调用而设计的。Invoke-Expression
,则它们可以从PowerShell**失败 *,即如果它们包含 * 未加引号的 * 字符,这些字符在cmd.exe
外部没有特殊含义,但在PowerShell中是 * 元字符 *,这适用于您的情况下的{
和}
。解决方案:
您有两种选择:
*(a)只需将卸载字符串原样传递给
cmd /c
cmd.exe
调用msiexec.exe
不同,通过cmd /c
调用会导致msiexec
的 * 同步 * 执行,这是理想的。***(B)将卸载字符串拆分为可执行文件和参数列表,允许您通过
Start-Process
**调用命令,可以更好地控制调用。-Wait
开关,以确保安装在脚本继续之前完成。注意:以下命令假定卸载字符串包含在变量
$UninstallString
(代码中的$UninstallPath.UninstallString
的等价物)中:执行(a):
然后可以查询自动
$LASTEXITCODE
变量以获得命令行的 * 退出代码 *。(B)的执行情况:
您还可以添加
-NoNewWindow
来防止 console 基于程序的卸载命令行在新的控制台窗口中运行,但请注意,通过Start-Process
捕获其stdout / stderr输出的唯一方法是使用-RedirectStandardOutput
/-RedirectStandardError
参数将其重定向到 files。特定版本/未来改进:
基于
Start-Process
的方法很麻烦,原因有两个:-ArgumentList
参数(因此需要上面的两个单独调用)。[1]如果你不介意额外的开销,你可以(暂时)从PowerShell(核心)导入Windows PowerShell
PackageManagement
模块,使用Windows PowerShell compatibility feature:Import-Module -UseWindowsPowerShell PackageManagement
.[2]如您的问题所示,它们存储在
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
(64位应用程序)和HKEY_LOCAL_MACHINE\Wow6432Node \Software\Microsoft\Windows\CurrentVersion\Uninstall
(32位应用程序)注册表项中。7uhlpewt2#
或者,例如: