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?
This means that if you hard code a Distinguished Name in PowerShell, and the string is enclosed in double quotes, any embedded double quotes must be escaped first by a backtick "`", and then by a backslash "\".
To pass a double quote, escape with a backslash: \" -> " To pass a one or more backslashes followed by a double quote, escape each backslash with another backslash and escape the quote: \\\\\" -> \\" If not followed by a double quote, no escaping is necessary for backslashes: \\ -> \\
There is no such difference between the single quote (') and double quote(“) in PowerShell. It is similar to a programming language like Python. We generally use both quotes to print the statements.
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 `$
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With