I am writing a script that uninstall Chrome and install specific version of this. I want to keep short this code but Invoke-Expression or Invoke-Command not working properly because the uninstall strings. How can write as short as possible?
$Uninstall =
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' | ForEach-Object {
Get-ItemProperty $_ | Where-Object {
$_.DisplayName -eq 'Google Chrome'
} | Select-Object -ExpandProperty 'UninstallString' | Invoke-Expression
}
Uninstall string: "C:\Program Files\Google\Chrome\Application\117.0.5938.92\Installer\setup.exe" --uninstall --channel=stable --system-level --verbose-logging
The simplest solution is to pass the uninstallation command line to cmd /c
:
$Uninstall =
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' |
Get-ItemProperty |
Where-Object {
$_.DisplayName -eq 'Google Chrome'
} |
ForEach-Object {
cmd /c $_.UninstallString
}
The problem with trying to use Invoke-Expression
is that it assumes PowerShell syntax, whereas the UninstallString
strings assume no-shell syntax, which - except in edge cases - also works from cmd.exe
.
For alternatives and additional information, see this answer.