1

I'm trying to run a PowerShell command in a batch script. Im trying to remove all traces of an old RMM tool from client PCs and for the life of me can't get this line to run correctly.

The idea is that this searches for software that has N-Able in the vendor name and passes the GUID to the $nableguid variable and then msiexec.exe against the GUIDs found above.

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {$nableguid = (Get -WmiObject Win32_Product -Filter "vendor LIKE '%N-able%'" | Select -ExpandProperty IdentifyingNumber); foreach ($nguid in $nableguid){ & MsiExec.exe /X$nguid /quiet} }";

The current error is as follows

Get-WmiObject : A positional parameter cannot be found that accepts argument ''. 
At line:1 char:18
+ & {$nableguid = (Get-WmiObject Win32_Product -Filter vendor LIKE '' | Select -Ex ...
+                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-WmiObject], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetWmiObjectCommand

I know that this boils down to orders of operations and the current organization of quotations, but after messing around with the ordering for an hour I still cant get it to work correctly.

2
  • The filter uses WQL syntax so try -Filter "Vendor LIKE '%N-able%'" Commented Jan 8, 2016 at 15:01
  • Also, it may be easier for you to build the command as a string prior to actually executing it. That will make it easier to sort out all the quotes. Commented Jan 8, 2016 at 15:03

3 Answers 3

1

Check this snippet, it is using WMI but in another way, and has almost never failed me :

function Uninstall-Application($computer, $target) {
    $productInfo = Get-WmiObject Win32_Product -Filter "Name LIKE '%$target%'" -ComputerName $computer
    $pin = $productInfo.IdentifyingNumber
    $pn = $productInfo.Name
    $pv = $productInfo.Version

    if($pn -ne $null) {
        $classKey = "IdentifyingNumber=`"$pin`",Name=`"$pn`",version=`"$pv`""

        $uninstallReturn = ([wmi]"\\$computer\root\cimv2:Win32_Product.$classKey").uninstall()
        if($uninstallReturn.ReturnValue -ge 0) { Write-Host "Uninstall complete" }
        else { $uninstallReturn | Out-Host }
    } else {
        Throw "Product not found"
    }
}

Example usage :

Uninstall-Application "127.0.0.1" "firefox"
Sign up to request clarification or add additional context in comments.

4 Comments

This is a nice script. Thank you for sharing it however there is one use case that doesn't seem to be handled unless I am missing something. I have multiple packages on my local desktop with the word "Zoom" in them as a result of having Zoom and support packages for ZoomText, a screen magnifier. When I attempt to remove Zoom this error occurs.
@PhillFernandes I guess you get a collection of ProductInfo, maybe you should try to iterate over it and run the rest of the code on each item?
OR target the product with the exact name with name='AppName'
@sodawilliow so Instead of Get-WmiObject Win32_Product -Filter "Name LIKE '%$target%'" are you suggesting Get-WmiObject Win32_Product -Filter "Name = '%$target%'" or Get-WmiObject Win32_Product -Filter "Name -eq '%$target%'".
0

You're getting that error, because you're using unescaped percent characters and double quotes inside a double-quoted string:

"& {... -Filter "vendor LIKE '%N-able%'" ...}"

The above evaluates to -Filter vendor LIKE '' when the PowerShell command is executed, i.e. only the token vendor is passed as an argument to the parameter -Filter. LIKE and '' are passed as separate positional parameters.

You must escape the nested double quotes to preserve them for the PowerShell command:

"& {... -Filter \"vendor LIKE '%N-able%'\" ...}"

You must also double the % characters (that's how they are escaped in batch/CMD), otherwise %N-able% would be interpreted as a batch variable and expanded to an empty string before the execution of the powershell commandline.

"& {... -Filter \"vendor LIKE '%%N-able%%'\" ...}"

With that said, in general it would be far simpler to implement the PowerShell code in a PowerShell script:

$nableguid = Get -WmiObject Win32_Product -Filter "vendor LIKE '%N-able%'" |
             Select -ExpandProperty IdentifyingNumber)

foreach ($nguid in $nableguid) {
  & MsiExec.exe /X$nguid /quiet
}

and run that script via the -File parameter (if you must run it from a batch file in the first place):

powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\path\to\script.ps1"

An even better approach would be to drop the batch script entirely and implement everything in PowerShell.

Comments

0

You can do it with uninstall-package:

get-package *name* | uninstall-package

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.