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