1

I'm trying create a uninstall script to uninstall any program tha I want.

I was using this script:

get-package -Name "XXXXX" | Uninstall-Package

But I saw that when the "provideName" attribut is "Program" it not working, so I use this.

$packageArray = get-package "*XXXX*"
foreach ($package in $packageArray){
$a = $package.ProviderName
if ($a -eq "Programs"){
& {($package.Meta.Attributes["UninstallString"]  -replace '"') /S}
}
if ($a -ne "Programs"){
get-package -Name "*XXXXX*" | Uninstall-Package
}
}

This part bellow was working fine when I have not ""&quot."", like this.

& {($package.Meta.Attributes["UninstallString"] -replace '"') /S}

Print: enter image description here

But now I'm getting erro when a uninstall string has "&quot." value, like this.

UninstallString=""&quot";C:\Users\rsantanna\AppData\Local\GoToMeeting\19950\G2MUninstall.exe" /uninstall"

Print. Example of ""&quot."" value

When it occur I get this error.

& : The term 'C:\Users\rsantanna\AppData\Local\GoToMeeting\19950\G2MUninstall.exe /uninstall' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:6 char:7

  • & ($UninstallString)
    
  •   ~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (C:\Users\rsanta....exe /uninstall:String) [], CommandNotFoundException
    • FullyQualifiedErrorId : CommandNotFoundException

Anyone can help me ?

1 Answers1

1
  • You cannot directly execute a string expression such as ($package.Meta.Attributes["UninstallString"] -replace '"')

  • While you can do so via &, the call operator, it only works if the string expression evaluates to a command name or executable file path only.

    • Notably, you can not use & to execute an entire command line, which is what $package.Meta.Attributes["UninstallString"] typically contains.

    • Note that your use of & is with a script block ({ ... }), which allows you to execute arbitrary statements contained in the block; however, perhaps needless to say, these statements are subject to the usual syntax rules, and it is the one and only statement in your block that causes a syntax error (that is actually different from the error you report).

As explained in detail in this answer, the command lines stored in UninstallString registry values are designed for invocation from cmd.exe or from no-shell environments.

Therefore, the simplest solution is to call via cmd.exe /c:

cmd.exe /c "$($package.Meta.Attributes["UninstallString"]) /S"

If your uninstall command line, as returned from $package.Meta.Attributes["UninstallString"], really contains " in lieu of verbatim " characters (double quotes) - which would be unusual - you'll need to replace the former with the latter first:

cmd.exe /c "$($package.Meta.Attributes["UninstallString"] -replace '"', '"') /S"

It's unclear what command produced the " output in your screenshot, but given that it shows the text of an XML document, the use of " instead of " is simply a necessity for encoding literal " chars.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Hi, thanks for helping. It work when I have no "&quot." value on "uninstallString", but when I have this it notwork and I recive the error "cmd.exe : 'C:\Program' is not recognized as an internal or external command," – Rafael Sant'Anna May 25 '22 at 15:10
  • I added prints in my questions, if you could, please check it. – Rafael Sant'Anna May 25 '22 at 15:20
  • @RafaelSant'Anna, are you saying that the uninstall string _literally_ contains `"` instead of `"`? It's unclear where your XML-based printout comes from. Normally, `$package.Meta.Attributes["UninstallString"]` contains values with _literal_ `"` embedded in them, if needed. In that event, the `cmd /c` call should succeed. If the `"` values are really present in what `$package.Meta.Attributes["UninstallString"]` returns, add `-replace '"', '"'` before the closing `)` inside `$(...)`. – mklement0 May 25 '22 at 15:38
  • 1
    Perfect. It works. I don't know why I did not think it before. Loks my script. $program = "*XXX*" $packageArray = get-package $program foreach ($package in $packageArray){ $a = $package.ProviderName if ($a -eq "Programs"){ cmd /c ($package.Meta.Attributes["UninstallString"] -replace '"' -replace '"') } if ($a -ne "Programs"){ get-package -Name $program | Uninstall-Package } } – Rafael Sant'Anna May 25 '22 at 16:44