7

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.

6
  • 5
    I'm pretty sure that error is from Invoke-Expression not Add-VM and you just need quotes around the argument: Invoke-Expression "Add-VM $argstr". Commented Oct 28, 2014 at 18:45
  • 2
    As an aside, why would I not just use Add-VM directly? This way just seems to add more typing. Commented Oct 28, 2014 at 18:47
  • @mikez while i agree with you, this module is for a product and the current users of a product are used to a certain syntax like i mentioned in the question. In the case of 'addvm', Add-VM makes sense but Delete is not a powershell verb so i had to use remove-vm for 'deletevm'. I'm trying to keep it as close to the original ssh shell on the product so that the transition is seamless. Commented Oct 28, 2014 at 19:42
  • Thanks @mikez. The ""s helped and got the job done. my bad. Commented Oct 28, 2014 at 19:47
  • 1
    If you want to use invocation as an abstraction layer you may want to use Invoke-Command -ScriptBlock { ... $args } -ArgumentList ... rather than Invoke-Expression "... $argstr". Commented Oct 28, 2014 at 20:07

2 Answers 2

12

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"
Sign up to request clarification or add additional context in comments.

Comments

5

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 }
    }
}

1 Comment

This is great. Thanks for posting. Another option, which i'm using, is an array and simply check to see if $command is an element in $cmdlist.

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.