I'm having an issue where it seems my encapsulated path is not being treated as encapsulted. I have tried a few different things, to no avail. I'm wondering if anyone has seen this before?
Function Remove-App-EXE-SILENT-QUOTES([String]$appName)
{
$appCheck = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object {$_.DisplayName -eq $appName } | Select-Object -Property DisplayName,UninstallString
if($appCheck -ne $null){
Write-host "Uninstalling "$appCheck.DisplayName
$uninst="`"" + ($appCheck.UninstallString) + "`""
Write-Host $uninst
cmd /C $uninst
}
else{
Write-Host "$appName is not installed on this computer"
}
}
Remove-App-EXE-SILENT-QUOTES "DELLOSD"
output is
PS C:\Program Files> C:\Users\HOL-OP05\Documents\RemoveDellOSD.ps1
Uninstalling DELLOSD
"C:\Program Files (x86)\InstallShield Installation Information\{50033799-D5D3-4759-9ABD-589AD04F33C1}\setup.exe -runfromtemp -l0x0009 -removeonly"
cmd : 'C:\Program' is not recognized as an internal or external command,
At C:\Users\HOL-OP05\Documents\RemoveDellOSD.ps1:8 char:9
+ cmd /C $uninst
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ('C:\Program' is...ternal command,:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
operable program or batch file.
Your attempt to enclose
$appCheck.UninstallStringin embedded"..."is unnecessary (and happens to make no difference in this case)PowerShell, when it constructs the process command line ultimately used behind the scenes, will automatically enclose the value of
$appCheck.UninstallStringin"...", if that value contains spaces[1], such as in the case at hand.Therefore, it should normally be enough to invoke the uninstallation command string as follows:
As Compo points out, your uninstallation command string is malformed: For it to work as intended when interpreted by
cmd.exe, the path of the executable inside the command must be enclosed in embedded"...", because it contains spaces; that is, the verbatim content of$appCheck.UninstallStringwould have to be (note how only thesetup.exefile path is enclosed in"..."):In other words: The root cause is that whatever installation application created the
UninstallStringregistry value in keyHKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstallon installation did so in a broken manner - see below for a potential workaround.An automated workaround workaround for such broken
UninstallStringstrings is possible, assuming that the executable path in the string explicitly uses the.exefilename extension:The above adds missing double quotes around an embedded executable path with spaces, and leaves already well-formed command-line strings alone.
This is achieved via the regex-based
-replaceoperator.Here is self-contained sample code:
Output:
[1] It actually neglects to escape
"characters that are embedded in such a value, but that is where broken worlds meet:cmd /cactually requires there to be no escaping. When targeting other console applications, however, PowerShell's broken behavior continues to cause problems in Windows PowerShell and caused problems in PowerShell (Core) 7 up to v7.2.x - see this answer for background information.