通过powershell从regedit获取应用程序的卸载字符串

dxxyhpgq  于 2023-03-18  发布在  Shell
关注(0)|答案(1)|浏览(695)

我一直在通过下面的脚本获得卸载字符串。
但我得到了这样的输出。

MsiExec.exe /I{629388F2-A011-4F5C-A6BF-98A80A25317C}

我想要的输出:

{629388F2-A011-4F5C-A6BF-98A80A25317C}

在期望的输出之后,我将把这个值赋给变量,比如$uninstallString。我将在doRemoveMSI函数中使用它,如下所示。

$paths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
Get-ChildItem $paths |
    Where-Object{ $_.GetValue('DisplayName') -match 'APP' } | 
    ForEach-Object{ 
        $uninstallString = $_.GetValue('UninstallString')
       
        $uninstallString
    }

doRemoveMSI -msi "msiexec.exe" -arguments '/x', '$uninstallString', '/quiet', 'REBOOT=R', '/L*V "C:\msilog.log"'
mgdq6dx1

mgdq6dx11#

顺便说一句:

  • 如果您使用的是 Windows PowerShell,并且只需要删除 * MSI安装的 * 应用程序,则更方便的解决方案是使用Uninstall-Package,正如js2010指出的那样;例如,

Get-Package -ProviderName msi *App* | Uninstall-Package

  • 如果您希望执行从注册表 as-is 中提取的UninstallString/QuietUninstallString命令行,请参见this answer

您的问题可以简化为如何从更大的字符串中提取{...}子字符串,您可以使用PowerShell的基于regex-replace运算符完成此操作:

# -> '{629388F2-A011-4F5C-A6BF-98A80A25317C}'
'MsiExec.exe /I{629388F2-A011-4F5C-A6BF-98A80A25317C}' -replace '^.+({.+?}).*$', '$1'

注意:{}是 * situational * 正则表达式元字符,但在这里按字面处理,因为它们不是有效量词子表达式的一部分(如o{2,3})。为了安全起见,您可以选择 always 将它们转义为\{\}
或者,您可以使用同样基于正则表达式的-split运算符,并通过{}(包括这些分隔符)将字符串拆分为标记,在look-aroundAssert的帮助下,提取第二个标记([1]):

# -> '{629388F2-A011-4F5C-A6BF-98A80A25317C}'
('MsiExec.exe /I{629388F2-A011-4F5C-A6BF-98A80A25317C}' -split '(?={)|(?<=})')[1]

请参阅this regex101.com page以了解正则表达式的详细解释和使用它的能力。注意,look-aroundAssert只匹配字符 * 位置 *,而不是实际字符,这使得{}能够包含在-split返回的令牌中。
或者.NET [string]类型的.Split() * 方法 *,传递要拆分的(文本)字符的 * 数组 *,使用可扩展的(双引号括起的)字符串("...")和$(...),子表达式运算符将提取的标记再次括在{}中。

# -> '{629388F2-A011-4F5C-A6BF-98A80A25317C}'
"{$( ('MsiExec.exe /I{629388F2-A011-4F5C-A6BF-98A80A25317C}').Split([char[]] '{}')[1] )}"

*说到 * 可扩展字符串

你电话里的那个,

doRemoveMSI -msi "msiexec.exe" -arguments '/x', '$uninstallString', '/quiet', 'REBOOT=R', '/L*V "C:\msilog.log"'

不会按预期工作,因为 NO 扩展(字符串插值)发生在'...'内部,即 verbatim(单引号)字符串。
虽然"$uninstallString"避免了这个问题,但是您甚至不需要"..."(除非需要显式的 * 到字符串转换 *),并且可以简单地按原样传递$uninstallString

至于如何 * 划分 * 传递给doRemoveMSI的参数(考虑重命名函数以符合PowerShell的命名约定,例如Uninstall-Msi):

  • this answer中对您上一个问题的讨论,如果您希望通过一个带有 * 嵌入式双引号 * 的 * 单个字符串 * 来传递参数 pairs -例如'/L*V "C:\msilog.log"'-那么传递一个 * 单个字符串overall* 会更简单,也就是说,将您的-arguments参数声明为[string]类型,然后调用函数,如下所示:
# Note the use of a *single* "..." string, 
# with *embeded* " chars. escaped as `"
doRemoveMSI -msi msiexec.exe -arguments "/x $uninstallString /quiet REBOOT=R /L*V `"C:\msilog.log`""

相关问题