kenorb
kenorb

Reputation: 166717

How to convert $args to a string and execute?

I'd like to pass all arguments that were given to the script and execute.

For example, given execute.ps1 script:

Invoke-Expression $($args[0])

I can run:

.\execute.ps1 hostname
myhostname

Same with two parameters with this script:

Invoke-Expression "$($args[0]) $($args[1])"

and executing it by:

.\execute.ps1 echo foo
foo

How I can make the script universal to support unknown number of arguments?

For example:

.\execute.ps1 echo foo bar buzz ...

I've tried the following combinations which failed:

Invoke-Expression $args

Invoke-Expression : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Command'. Specified method is not supported.


Invoke-Expression [system.String]::Join(" ", $args)

Invoke-Expression : A positional parameter cannot be found that accepts argument 'System.Object[]'.


Invoke-Expression $args.split(" ")

Invoke-Expression : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Command'. Specified method is not supported.


Invoke-Expression [String] $args

Invoke-Expression : A positional parameter cannot be found that accepts argument 'System.Object[]'.

Upvotes: 5

Views: 9491

Answers (3)

briantist
briantist

Reputation: 47832

I recommend Bill_Stewart's answer to avoid issues with the command itself (first argument) having spaces. But even with that answer, you would have to be careful to individual quote arguments, with the caveat that that itself itself a complicated thing.


You can just do:

 Invoke-Expression "$args"

By default converting to a string that way will join it with spaces (technically, join it with the default output field separator, which is the value of $OFS, which defaults to a space).

You can also do a manual join as in Wayne's answer.

Upvotes: 11

Bill_Stewart
Bill_Stewart

Reputation: 24585

My recommendation would be to avoid Invoke-Expression and use & instead. Example:

$command = $args[0]
$params = ""
if ( $args.Count -gt 1 ) {
  $params = $args[1..$($args.Count - 1)]
}
& $command $params

Of course, parameters containing spaces would still need to contain embedded quotes.

Upvotes: 3

WayneA
WayneA

Reputation: 339

$args is a whitespace delimited array of strings created from the imput

   Invoke-Expression -Command "$($args -join " ")"

Re-joining it with a whitespace character, and passing it to invoke-expression as a string works for me.

Upvotes: 4

Related Questions