将 string[] 从批处理文件(包含双引号 ")传递给 powershell 脚本

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

我有一个 powershell 脚本,它有一个 string[] 参数,并尝试从批处理文件向它传递值

PowerShell 脚本

[string[]]$ScriptArgs

批处理文件

powershell -File Foobar.ps1 -ScriptArgs -versn="""1.0.0.0""",pattern="""FooBar.*"""

(3 条引述 - 对于 escaping/showing 1 条引述)

但无论我做什么 Write-Host $ScriptArgs.Count 打印 1

我想让变量接收2个元素

[0] 将是 -versn="1.0.0.0"
[1] 将是 -pattern="FooBar.*"


在批处理文件中,我什至尝试单独设置变量

set @sArgs = -versn="""1.0.0.0"""
set @sArgs = %sArgs%;-pattern="""FooBar.*"""
powershell -File Foobar.ps1 -ScriptArgs %sArgs%

但是控制台不知何故 运行 就好像没有创建变量一样 运行 它是

powershell -File Foobar.ps1 -ScriptArgs

并抛出错误

Missing an argument for parameter 'ScriptArgs'. Specify a parameter of type System.String[] and try again

我应该改变什么来实现这个目标?

批处理文件(来自cmd.exe)调用PowerShell脚本时-File,没有没有的方法可以直接将值数组传递给PowerShell array参数:

  • 如果指定的数组值不带空格,则它们被视为一个 SINGLE 元素;例如:

    • one,two,three 成为单个数组元素
  • 如果使用空格,尾随逗号成为参数的一部分,并且只有第一个值绑定到数组参数:

    • one, two, three - one, - 包括尾随 , - 成为 only 数组元素,two,three, 被认为是 单独的 个参数。

解决方法 是:

  • 任一使用-Command调用脚本-见底部。

  • 或者,使用 -File,以不同方式声明参数并以不同方式传递参数:

    • 属性修饰数组参数 [Parameter(ValueFromRemainingArguments)]
    • 将数组元素作为单独传递,space-separated参数不带参数名称 .

你的情况:

  • 声明参数:

    [Parameter(ValueFromRemainingArguments)]
    [string[]] $ScriptArgs
    
  • 单独的space-separate参数调用脚本前面没有参数名绑定它们作为 $ScriptArgs:

    的数组
    powershell -File Foobar.ps1 "-versn=\"1.0.0.0\"" "pattern=\"FooBar.*\""
    
    • 注意引用:

      • 每个参数 作为一个整体 包含在 "..." 中 - 这不是绝对必要的,但可以防止 -- -version 等前缀值被误认为是参数名称。

      • " 个字符。保留为 文字 \-转义(这与必须从 within[=175= 使用的 `-转义形成对比] PowerShell).

此方法的固有限制

  • 方法不支持多个数组参数,因为只有一个可以用ValueFromRemainingArguments修饰。

  • 不能传递任何其他参数位置(即,您必须在参数之前使用参数名称传递给其他参数)。


备选方案:使用 -Command 而不是 -File

powershell -command "./Foobar.ps1 '-versn=\"1.0.0.0\"', '-pattern=\"FooBar.*\"'"

注:

  • 您传递给 -Command 的内容被视为一段 PowerShell 代码 - 无论您传递一个 single 参数或 多个 参数 - 在后一种情况下,它们只是 concatenated 与空格和 result 然后被解释为 PowerShell 代码。

  • 含义是:

    • 要在当前目录中执行脚本,您必须使用 path (.\) 引用它 - 为了执行它.

      • 此外,如果脚本路径包含空格或其他 shell 元字符,您必须引用它并通过调用运算符 & 调用它;例如,& '.\Foo Bar.ps1'
    • 您可以照常传递数组参数,除了 " 字符。必须再次转义为 \",而不是 `".

    • 还要注意,参数再次被引用 作为一个整体 (也是),在这种情况下 required 以防止 PowerShell 将 -versn-pattern 解释为参数名称。

      • 考虑到整个命令必须在 "..." 中传递,用 " 执行嵌入式引号,这仍然是可能的,这是非常尴尬的,因为你必须 combine \- 和 `- 转义;例如,\"-pattern=`\"FooBar.*`\"\"
    • 通常,请注意所有常用的 PowerShell 解析规则都适用,因此,例如,要使用 literal $,您必须将其转义为 `$.