Search code examples
stringpowershellsplituninstallation

Would like a universal way to split different strings into multiple parts using PowerShell


I am working on a method of reading UninstallStrings for software from the registry. And then I'm trying to execute those strings to uninstall the software.

When I print out the variables that hold the string info, it prints the whole string (with the arguments) correctly, but I am unable to run those strings. There are multiple parts to this issue.

Some install strings are formatted like so

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

What I'm trying to do is figure out the best way to be able to run the uninstaller in a "universal" way. Is there a way to do this effectively?

I tried executing the strings 2 different ways.

    & $uninstaller

and

    Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninstaller -Wait 

Neither of them seem to work. No errors, but they don't seem to run because when I check the app it's still installed.

And I tried splitting the text a few ways.


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

Thanks in advance!


Solution

  • Try the following testing script, where simple console application CliParser.exe merely echoes command line arguments (written in C, inspired here). Used the exact copy with a space in name CliParser noPause.exe; it shows that . $Uninstaller $UninsParams should work even if a path $Uninstaller contains space(s).

    No need to use Start-Process -FilePath cmd.exe …; just apply the dot-sourcing operator as . $Uninstaller $UninsParams

    The $lines collection contains an almost representative syntax patterns of uninstall strings (taken from my Windows 10):

    $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 = *" }
    }
    

    Output: D:\PShell\SO\62023960.ps1

    . 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