如何通过 vbscript 将字符串数组传递给 powershell?

How to pass a string array to powershell through vbscript?

我正在尝试通过 vbscript 将字符串数组传递给 powershell。 我在文件中得到了参数。ps1 脚本:

param (
    [string[]]$target
)

我正在尝试调用文件。ps1 通过 vbscript。

我要$target = @('c:\dev','d:\lib') 传入

我目前在我的 vbscript 中有 :-

target1 = """c:\dev"", ""d:\lib"""
Set objShell = CreateObject("Wscript.Shell") 
objShell.run("powershell.exe -noexit -ExecutionPolicy Unrestricted -file .\file.ps1 -target1 """ & target & """")

哪个returns: c:\dev, d:\lib 而不是 powershell 字符串数组格式 "c:\dev", "d:\lib"

更新 - 感谢 mklement0alex-dl 的回答!

您可以使用以下 vbscript:

target1 = """c:\dev, d:\lib"""
Set objShell = CreateObject("Wscript.Shell") 
objShell.run("powershell.exe -Command .\file.ps1 -target " & target1)

还有这个 powershell 脚本:

param (
    [string[]]$target
)
foreach ($t in $target) {
    write-output $t
}
Read-Host -Prompt "Press Enter to exit"

在没有 -Command 的情况下,参数始终被解释为单个字符串。

包含一个有效的解决方案,只要数组的元素不需要引用,但让我尝试在概念上更详细地分解它:

  • PowerShell (Core) 7+) 中 PowerShell CLI, powershell.exe (pwsh-File 参数 从根本上说 not 支持将 arrays 传递给 PowerShell 代码,因为所有参数都被严格解释为 whitespace -分隔,逐字内容.

    • 例如,命令行上的 "c:\dev", "d:\lib" 被解析为 两个 个参数:
      • c:\dev,(注意尾部 ,,句法 " 引号被删除)
      • d:\lib
  • 您必须使用 -Command (-c) 选项才能传递数组.

    • -Command 从根本上改变了参数的解析方式:
      • 所有参数都去除了句法(非 \"-转义)" 引号。
      • 生成的标记被 space 连接形成一个字符串。
      • 生成的字符串 然后 解释为 PowerShell 代码,也就是说,就好像你有从 PowerShell 会话中提交。
    • 因此,这将启用 PowerShell 的所有功能,例如使用 ,'...'(单引号)...传递数组,特别是还意味着对 [=71= 的引用]PowerShell 变量(例如 $HOME 识别(与 -File 不同)。

有关何时使用 -File-Command (-c) 的更多指导,请参阅

因此,您的情况的最佳方法是:

target = "'c:\dev', 'd:\lib'" ' Note the embedded '...'-quoting
Set objShell = CreateObject("Wscript.Shell") 
' Note the use of -c (-command) instead of -file
objShell.Run("powershell.exe -noexit -ExecutionPolicy Unrestricted -c .\file.ps1 -target " & target)

使用嵌入式 '...'-quoting 简化了传递数组元素的方式,PowerShell 将它们视为 单独 引用(使用手头的值,这不是绝对必要,但在其他情况下可能是必要的)。

使用嵌入的 "..." 引用变得笨拙,因为每个嵌入的 " 必须转义为 \""(原文如此):

  • "" 转义 VBScript 字符串中的 "
  • \以确保\"最终在命令行上传递,PowerShell需要在命令行上转义" ][1](而 PowerShell- 内部 ,它是 `" 或(或者,在双引号字符串中)"").
target = "\""c:\dev\"", \""d:\lib\"""
Set objShell = CreateObject("Wscript.Shell") 
objShell.Run("powershell.exe -noexit -ExecutionPolicy Unrestricted -c .\file.ps1 -target " & target)

[1] 在 Windows PowerShell 中,您可以 情境 逃脱 "" 而不是 \",它可以 破坏 ,尤其是当整个 -c 参数包含在 "..." 中时。 此问题已在 PowerShell (Core) 7+ 中 修复,您现在可以在其中交替使用 ""\"
例如,从 cmd.exe
调用时 powershell -c " ""ab c"".length " 中断,而
pwsh -c " ""ab c"".length " 有效.