Uninstalling using Get-WmiObject

半城伤御伤魂 提交于 2019-12-20 05:16:17

问题


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.


回答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"



回答2:


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.



来源:https://stackoverflow.com/questions/34679597/uninstalling-using-get-wmiobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!