Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling Invoke-Expression with Parameters in Powershell

I've written a powershell module in c# that has a bunch of cmdlets like

Add-VM

The cmdlets reach out to an API and pull data back.

but for the sake of uniformity with the ssh CLI of the product, i've written a function called newtask that accepts 'addvm' as an argument and $args.

for example

newtask addvm -id 12345

I then invoke Add-VM and pass $args as a string like so

Invoke-Expression Add-VM $argstr

The problem is that Add-VM throws an error that it cannot find a positional parameter that accepts argument System.Object[]

A positional parameter cannot be found that accepts argument 'System.Object[]'

While I could easily alias 'addvm' to 'Add-VM', i'm trying to maintain uniformity with the ssh CLI so that new users can quickly start utilizing this module.

I figured that sending a string like '-id 12345' would suffice but it's not. Does the pscmdlet expect to receive something else?

Thanks in advance.

like image 595
anoopb Avatar asked Oct 28 '14 18:10

anoopb


People also ask

How do you pass parameters to invoke in PowerShell?

To pass the argument in the Invoke-command, you need to use -ArgumentList parameter.

What does invoke-expression do in PowerShell?

The Invoke-Expression cmdlet evaluates or runs a specified string as a command and returns the results of the expression or command. Without Invoke-Expression , a string submitted at the command line is returned (echoed) unchanged. Expressions are evaluated and run in the current scope.

What does $() mean in PowerShell?

Subexpression operator $( ) For a single result, returns a scalar. For multiple results, returns an array. Use this when you want to use an expression within another expression. For example, to embed the results of command in a string expression. PowerShell Copy.

How do I add a parameter to a PowerShell script?

A default value will not work with a mandatory parameter. You can omit the =$true for advanced parameters of type boolean [Parameter(Mandatory)] . @Andrew First of all you have to change the type of the parameter to [string] . If you then want to pass a string as parameter you can use either ' or " .


2 Answers

I know this is a little old now, but I was having a similar issue and a co-worker showed me that escaping $argstr prevents the object from getting converted to a string.

Invoke-Expression "Add-VM `$argstr"
like image 65
getSurreal Avatar answered Nov 15 '22 07:11

getSurreal


That error is from Invoke-Expression not Add-VM and you just need quotes around the argument:

Invoke-Expression "Add-VM $argstr"

This has the drawback of forcing all objects into string format. This might be acceptable for simple types like ints and strings but if you want to pass through a more complex object it won't work. An alternative would be to splat the arguments with @args but I don't think you can do this through Invoke-Expression or Invoke-Command. You need to directly call the cmdlet:

function newtask {
    params([string]$command)

    switch ($command) {
        "addvm" { Add-VM @args }
        "deletevm" { Remove-VM @args }
    }
}
like image 4
Mike Zboray Avatar answered Nov 15 '22 08:11

Mike Zboray