Execute-Process "illegal characters in path"

I keep getting an “Illegal characters in path” error when the script gets to the Execute-Process line in this code snippet. I don’t understand why. The actual value that $uninstallString returns when I run it under Powershell ISE is “C:\Program Files (x86)\Australian Monitor\ZONEMIX\ZONEMIX Control Software 1.3.0\uninstall.exe” and when I put that value in place of $uninstallString, the script works.

foreach ($regPath in $regPaths) {
            # Get all subkeys (applications) from the registry path
            $keys = Get-ChildItem -Path $regPath

            foreach ($key in $keys) {
                # Get the display name and uninstall string
                $displayName = (Get-ItemProperty -Path $key.PSPath -Name "DisplayName" -ErrorAction SilentlyContinue).DisplayName
                $uninstallString = (Get-ItemProperty -Path $key.PSPath -Name "UninstallString" -ErrorAction SilentlyContinue).UninstallString

                # Check for partial match
                if (($displayName -like $partialAppName) -and ($uninstallString -ne $null)) {
                    if ($uninstallString.StartsWith("msiexec.exe /i",'CurrentCultureIgnoreCase') ) {
                        $msiProductCode = $uninstallString -replace "msiexec.exe /i"
                        Execute-MSI -Action 'Uninstall' -Path "$msiProductCode"
                    } else {
                        Execute-Process -Path "$uninstallString"
                    }
                }
            }
        }

maybe not the answer, but I usually do a write-host “Uninstallstring: $Uninstallstring”
then you can possibly see what’s being presented to the variable to troubleshoot this kinda stuff.

1 Like

You often don’t get what you expect. For example, the uninstall value often contains -silent or something else. This means you have to split the string. I use this code to uninstall:

$ustr=Get-InstalledApplication -name “AnyDesk” -WildCard
Write-Log -Message “IF older $($appVendor) $($appName) Installation exist, start Uninstall” -LogType ‘CMTrace’
foreach ($ustring in $ustr)
{
$prod=$ustring.ProductCode

		if ($prod -eq "")
		{ ## irgend eine Installation e.g. WEB-Installer
			$unstr= $ustring.UninstallString + " --silent"
			$unstring=$unstr.split('"')
			Write-Log -Message "start Uninstall $($unString[1]) $($unString[2])" -LogType 'CMTrace' 
			$erg=start-process $unString[1] -arg "--remove --silent" -Wait
			Write-Log -Message "$($appVendor) $($appName) has been removed with" -LogType 'CMTrace'
		}
		else
		{ ## MSI Installation!
			Write-Log -Message "start MSI Uninstall $($prod)" -LogType 'CMTrace'
			$ExeResult=Execute-MSI -Action 'Uninstall' -Path $prod -Parameters "/qn" -ContinueOnError $True -passthru -IgnoreExitCodes *
            Write-Log -Message "$($appVendor) $($appName) has been removed" -LogType 'CMTrace'
		}
	}

Maybe there’s a hidden whitespace or ctrl character in the registry value. Visual Studio Code is good at rendering these to help you understand if there’s something in there unexpected that you can’t see. I’d try copying the value of the registry key from regedit and pasting it into vscode to see if it can show you.

I’ve found this function really helpful to return the unistall string from devices (originally sourced from here: Cheatsheet for PSAppDeployToolkit – SIMSEN blog)

## function to assist finding uninstall strings, msi codes, display names of installed applications
# paste into powershell window (or save in (powershell profile)[http://www.howtogeek.com/50236/customizing-your-powershell-profile/]
# usage once loaded: 'Get-Uninstaller chrome'
function Get-Uninstaller {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = $true)]
    [ValidateNotNullOrEmpty()]
    [string] $Name
  )
 
  $local_key     = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
  $machine_key32 = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
  $machine_key64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
 
  $keys = @($local_key, $machine_key32, $machine_key64)
 
  Get-ItemProperty -Path $keys -ErrorAction 'SilentlyContinue' | ?{ ($_.DisplayName -like "*$Name*") -or ($_.PsChildName -like "*$Name*") } | Select-Object PsPath,DisplayVersion,DisplayName,UninstallString,InstallSource,InstallLocation,QuietUninstallString,InstallDate
}
## end of function

I have found sometimes with Get-ItemProperty I have to use -literalpath instead of just path.