Passing string[] from batch file (which contains double quotes ") to powershell script

前端 未结 1 2020
醉梦人生
醉梦人生 2020-12-19 10:56

I have a powershell script which has a string[] parameter and try to pass value to this from batch file

PowerShell Script



        
相关标签:
1条回答
  • 2020-12-19 11:25

    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:

    • 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.

        • Additionally, if the script path contains whitespace or other shell metacharacters, you must quote it and invoke it via &, 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.

        • Given that the overall command must be passed inside "...", 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 `$.

    0 讨论(0)
提交回复
热议问题