String 想要使用PowerShell将不同字符串拆分为多个部分的通用方法吗

String 想要使用PowerShell将不同字符串拆分为多个部分的通用方法吗,string,powershell,split,uninstallation,String,Powershell,Split,Uninstallation,我正在研究一种从注册表读取软件卸载字符串的方法。然后我尝试执行这些字符串来卸载软件 当我打印出保存字符串信息的变量时,它会正确地打印整个字符串(带参数),但我无法运行这些字符串。 这个问题有多个部分 一些安装字符串的格式如下 c:\file path\blah\app.exe /uninstall "c:\file path\blah\app.exe" /uninstall c:\file path\blah\app.exe --uninstall 'c:\file path\blah\app.

我正在研究一种从注册表读取软件卸载字符串的方法。然后我尝试执行这些字符串来卸载软件

当我打印出保存字符串信息的变量时,它会正确地打印整个字符串(带参数),但我无法运行这些字符串。 这个问题有多个部分

一些安装字符串的格式如下

c:\file path\blah\app.exe /uninstall
"c:\file path\blah\app.exe" /uninstall
c:\file path\blah\app.exe --uninstall
'c:\file path\blah\app.exe' /uninstall
我想做的是找出以“通用”方式运行卸载程序的最佳方法。 有没有办法有效地做到这一点

我尝试了两种不同的方式执行字符串

    & $uninstaller

他们两个似乎都不起作用。没有错误,但它们似乎没有运行,因为当我检查应用程序时,它仍在安装

我试着用几种方法来拆分文本


    $Uninstaller.split("/")[0]
    $Uninstaller.split("/",2)[1]
    $($Uninstaller) | Invoke-Expression
    $Uninstaller.Substring(0,$Uninstaller.lastIndexOf('.exe '))
    $Uninstaller.split('^(*?\.exe) *')


提前谢谢

找到了答案。也许有更好的方法,但这似乎对我很有效

CLS

$Software = "OneDrive"
$Filter = "*" + $Software + "*"
$Program = $ProgUninstall = $FileUninstaller = $FileArg = $NULL

try 
{
    if (Test-Path -Path "HKLM:\SOFTWARE\WOW6432Node") 
    {
        $programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
    }

    $programs += Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
    $programs += Get-ItemProperty -Path "Registry::\HKEY_USERS\*\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
} 
catch 
{
    Write-Error $_
    break
}

foreach($Program in $Programs)
{
    $ProgDisplayName = $Program.DisplayName
    $ProgUninstall = $Program.UninstallString

    if($ProgDisplayName -like $Filter)
    {
        if($ProgUninstall -like "msiexec*")
        {
            $FileUninstaller = $ProgUninstall.split(" ")[0]
            $FileArg = ($($ProgUninstall).split(" ",2)[1])
        }
        else
        {
            if(($ProgUninstall -like '"*"*') -or ($ProgUninstall -like "'*'*"))
            {
                #String has quotes, don't need to do anything

            }
            else
            {
                if($NULL -ne $ProgUninstall)
                {
                    #String doesn't have quotes so we should add them
                    $ProgUninstall = '"' + ($ProgUninstall.Replace('.exe','.exe"'))                    
                }
            }

            #Let's grab the uninstaller and arguments
            $FileUninstaller = $ProgUninstall.split('"')[1]
            $FileArg = $ProgUninstall.split('"')[-1]
        }

        #Debug
        #$FileUninstaller
        #$FileArg

        #Run the Uninstaller
        Start-Process $FileUninstaller -ArgumentList $FileArg -wait -ErrorAction SilentlyContinue
    }
}

这对于msi安装非常容易:

get-package *whatever* | uninstall-package
下面是一个非msi静默卸载示例,但您必须添加“/s”或静默卸载选项:

get-package notepad++* | 
  % { & $_.Meta.Attributes['UninstallString'] /S }

尝试下面的测试脚本,其中简单控制台应用程序
CliParser.exe
仅回显命令行参数(用C编写,受启发)。使用名称
CliParser noPause.exe
中带有空格的精确副本;它显示
$即使路径
$Uninstaller
包含空格,卸载程序$UninsParams也应工作

无需使用
启动进程-FilePath cmd.exe…
;只需将点源操作符应用为
$卸载程序$UninsParams

$lines
集合包含几乎具有代表性的卸载字符串语法模式(取自我的Windows 10):

输出
D:\PShell\SO\62023960.ps1

. MsiExec.exe/X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} 参数1=/X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} . “D:\Program Files(x86)\Virtual Russian Keyboard\unins000.exe” . C:\Windows10Upgrade\Windows10UpgraderApp.exe/卸载 参数1=/Uninstall . C:\Windows\SysWOW64\msiexec.exe/package{CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE}/uninstall{815F0BC1-7E54-300C-9ACA-C9460FDF6F78}/qb+REBOOTPROMPT=“” 参数1=/package 参数2={CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} 参数3=/uninstall 参数4={815F0BC1-7E54-300C-9ACA-C9460FDF6F78} 参数5=/qb+ 参数6=REBOOTPROMPT=“” . “C:\Program Files(x86)\InstallShield安装信息\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe”-runfromtemp-removeonly 参数1=-runfromtemp 参数2=-removeonly . C:\WINDOWS\SysWOW64\RunDll32.exe“C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL”,卸载软件包显示。驱动程序 参数1=C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL,卸载软件包 参数2=显示驱动程序 . C:\WINDOWS\system32\sdbinst.exe-u“C:\WINDOWS\AppPatch\CustomSDB\{9F4A9B-eec5-4906-92fe-d1f43ccf5c8d}.sdb” 参数1=-u 参数2=C:\WINDOWS\AppPatch\CustomSDB\{9F4A9B-eec5-4906-92fe-d1f43ccf5c8d}.sdb
我想您需要用双引号将
app.exe
的完整路径括起来?例如,后者为
'c:\file path\blah\app.exe'/uninstall
“c:\file path\blah\app.exe”/uninstall
?感谢您的回复,问题是,注册表中的所有卸载字符串都使用该语法。这就是为什么这有点复杂。一些卸载字符串是msiexec,另一些是带有自定义参数的可执行卸载程序。并不是所有的论点都是普遍的。它们基于可执行文件。一个exe可能有破折号,另一个是正斜杠。谢谢分享。这似乎比我在下面发布的决议要好。它基本上用更少的代码行做同样的事情,所以我更喜欢你的。我唯一看不懂的是最后一行(卸载程序部分),它似乎不适合我。我尝试使用&$file,但仍然没有结果。无论如何,我是通过使用Start Process$Uninstaller-ArgumentList$UninsParams-waitThe
实现的$如果
echo
ed字符串包含空格,卸载程序$UninsParams
可能会失败,因为
cmd
会添加周围的双引号。例如,
$y='ab';echo$y;cmd/c echo$y;cmd/c“echo$y”
返回字符串
ab
ab
。但是,正确转义
cmd/c echo$($aux[0].TrimStart(“”).TrimStart(“”+”.exe')
中的所有双引号似乎是一个棘手的问题。只需使用一个附加的辅助变量,或作为
$Uninstaller=(cmd/c echo$($aux[0].TrimStart(“).TrimStart(“”+”.exe')).Trim(““”)
,请参阅更新的答案。您好,我进行了调整。您拥有的最后一行,我使用调整以适合我的示例:.$Uninstaller$UninsParams | Where Object{$\不象“param 0=*”}但是,我得到以下错误::术语“C:\Program Files(x86)\Microsoft OneDrive\20.064.0329.0008\U 7\OneDriveSetup.exe”不能识别为cmdlet、函数、脚本文件或可操作程序的名称。请检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。“对不起,我的错误。在
$Uninstaller=(cmd/c echo$($aux[0]。TrimStart(“”).TrimStart(“”+”.exe'))中,已调整(作为回答)缺少最左侧的左括号。Trim(“”)
…感谢您的更新回复,但就我的情况而言,我希望它尽可能无缝。我在下面发布了一个我认为对我来说似乎很有效的解决方案,但JoesefZ的解决方案似乎更好。它的输出与我的完全相同(这是我所需要的),代码更少,所以我觉得这是最好的答案。
get-package notepad++* | 
  % { & $_.Meta.Attributes['UninstallString'] /S }
$lines = @'
MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF}
"D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe"
"C:\Windows10Upgrade\Windows10UpgraderApp.exe" /Uninstall
C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT=""
C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe -runfromtemp -removeonly
"C:\WINDOWS\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver
%windir%\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb"
'@ -split [System.Environment]::NewLine

$FakeUninstaller = "D:\bat\CLIParser noPause.exe"

foreach ( $line in $lines ) {
    # $line
    $aux = $line -split @('\.exe'),2,[System.StringSplitOptions]::None
    $Uninstaller = (cmd /c echo $($aux[0].TrimStart('"').TrimStart("'") + '.exe')).Trim('"')
    $UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)

    ". $Uninstaller $UninsParams"
    . $FakeUninstaller $UninsParams | Where-Object { $_ -notlike "param 0 = *" }
}
. MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} param 1 = /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} . "D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe" . C:\Windows10Upgrade\Windows10UpgraderApp.exe /Uninstall param 1 = /Uninstall . C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT="" param 1 = /package param 2 = {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} param 3 = /uninstall param 4 = {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} param 5 = /qb+ param 6 = REBOOTPROMPT="" . "C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe" -runfromtemp -removeonly param 1 = -runfromtemp param 2 = -removeonly . C:\WINDOWS\SysWOW64\RunDll32.exe "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver param 1 = C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL,UninstallPackage param 2 = Display.Driver . C:\WINDOWS\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb" param 1 = -u param 2 = C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb