I have a powershell script which has a string[]
parameter and try to pass value to this from batch file
PowerShell Script
When calling a PowerShell script from from a batch file (from cmd.exe
) with -File
, there is no way to directly pass an array of values to a PowerShell array parameter:
If you specify the array values without spaces, they are considered a SINGLE element; e.g.:
one,two,three
becomes a SINGLE array elementIf you do use spaces, the trailing commas become part of the arguments, and only the FIRST value is bound to the array parameter:
one, two, three
- one,
- including the trailing ,
- becomes the only array element, two,
and three,
are considered separate arguments.The workarounds are to:
Either: use -Command
to invoke the script - see bottom section.
Or, with -File
, declare the parameter differently and pass arguments differently:
[Parameter(ValueFromRemainingArguments)]
In your case:
Declare the parameter:
[Parameter(ValueFromRemainingArguments)]
[string[]] $ScriptArgs
Invoke the script with separate, space-separate arguments not preceded by the parameter name to bind them as an array to $ScriptArgs
:
powershell -File Foobar.ps1 "-versn=\"1.0.0.0\"" "pattern=\"FooBar.*\""
Note the quoting:
Each argument as a whole is enclosed in "..."
- this isn't strictly necessary, but guards against -
-prefixed values such as -version
being mistaken for parameter names.
"
chars. to be retained as literals are \
-escaped (which contrasts with the `
-escaping that must be used from within PowerShell).
The inherent limitations of this approach:
The approach doesn't support multiple array parameters, because only one can be decorated with ValueFromRemainingArguments
.
You cannot pass any other arguments positionally (i.e., you must precede arguments to pass to other parameters with their parameter name).
Alternative: Using -Command
instead of -File
:
powershell -command "./Foobar.ps1 '-versn=\"1.0.0.0\"', '-pattern=\"FooBar.*\"'"
Note:
What you pass to -Command
is treated as a piece of PowerShell code - whether you pass a single argument or multiple ones - in the latter case, they are simply concatenated with spaces and the result is then interpreted as PowerShell code.
The implications are:
To execute a script in the current directory, you must refer to it with a path (.\
) - in order to execute it.
&
, the call operator; e.g., & '.\Foo Bar.ps1'
You can pass array arguments as usual, except that "
chars. must again be escaped as \"
, not `"
.
Also note that again the arguments are quoted as a whole (too), which in this is case required to prevent PowerShell from interpreting -versn
and -pattern
as parameter names.
"..."
, performing the embedded quoting with "
, which still possible, is quite awkward, because you then have to combine \
- and `
-escaping; e.g., \"-pattern=`\"FooBar.*`\"\"
Generally, be aware that all usual PowerShell parsing rules apply, so that, for instance, to use a literal $
, you must escape it as `$
.