I have a powershell script which has a string[]
parameter and try to pass value to this from batch file
PowerShell Script
[string[]]$ScriptArgs
Batch File
powershell -File Foobar.ps1 -ScriptArgs -versn="""1.0.0.0""",pattern="""FooBar.*"""
(3 Quotes - For escaping/showing 1 quote)
But no matter what I do Write-Host $ScriptArgs.Count
prints 1
I want the variable to receive 2 elements
[0]
will be -versn="1.0.0.0"
[1]
will be -pattern="FooBar.*"
In batch file, I even tried setting variables individually
set @sArgs = -versn="""1.0.0.0"""
set @sArgs = %sArgs%;-pattern="""FooBar.*"""
powershell -File Foobar.ps1 -ScriptArgs %sArgs%
but the console somehow runs as if the variable is not created and run it as
powershell -File Foobar.ps1 -ScriptArgs
and throws error
Missing an argument for parameter 'ScriptArgs'. Specify a parameter of type System.String[]
and try again
What should I change to achieve this?
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 element
If 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:
- decorate the array parameter with attribute
[Parameter(ValueFromRemainingArguments)]
- and to pass the array elements as individual, space-separated arguments, without their parameter name.
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: