【问题标题】:Call PowerShell Script From Batch File With All Parameters使用所有参数从批处理文件调用 PowerShell 脚本
【发布时间】:2018-02-20 04:24:40
【问题描述】:

This questionthis blog post 解决了如何将特定参数从批处理文件传递到 PowerShell 脚本。

如何将所有参数传递到 PowerShell 脚本中?基本上我想 splat 所有参数,以便批处理文件透明地传递所有参数。

编辑以获得更多上下文:

我目前正在使用这样的一行:

PowerShell.exe -Command "& '%~dpn0.ps1' '%1' '%2'"

这可行,但会在文件之间创建冗余,因此,如果我更新 PowerShell 脚本以采用不同的参数,我也必须更新批处理脚本。如果我能做这样的事情就好了:

PowerShell.exe -Command "& '%~dpn0.ps1' '%*'"

【问题讨论】:

  • 你能提供一个你想要的例子吗? Cmd 没有像 PSv3+ 那样飞溅。
  • @TheIncorrigible1 我目前使用像PowerShell.exe -Command "& '%~dpn0.ps1' '%1' '%2'"这样的行;我希望能够传递所有参数而不必枚举它们。
  • 我不确定这是否可行或如何,但最好能像PowerShell.exe -Command "& '%~dpn0.ps1' '%*'"

标签: windows powershell batch-file


【解决方案1】:

尝试以下方法:

powershell -File "%~dpn0.ps1" %*
  • 在批处理文件中,%* 代表所有传递的参数。[1]

  • -File 是用于通过 PowerShell 的 CLI 调用 脚本 的参数。

  • 所有剩余的参数都按原样传递(而-Command 将使它们接受 PowerShell 的另一轮解释[2] )。

[1] 请注意,要使 cmd.exe(批处理文件)将带有嵌入空格的参数识别为单个参数,您必须将其括在 "..." 中。
例如,如果您想将参数ab c 传递给批处理文件file.cmd,则必须将其命名为
file a "b c"
要传递 嵌入 " 实例,\-转义它们;例如,"\"b c\"" 使 PowerShell 看到 "b c",包括双引号。
如果您遵守这些规则,%* - 不带引号 - 正确传递参数数组。
不要使用"%*" - 它不会按预期工作。

[2] 实际上,-Command 导致后面的所有参数都由一个空格连接,然后 结果字符串 被解释为 PowerShell 命令 - 也就是说,在参数被cmd.exe(批处理文件)的规则解析之后,它们会被PowerShell进行另一轮的解析。
不幸的是,PowerShell 一直以这种方式工作,但是这种行为是模糊的,并且可能会在 Unix 世界中引起更多的混乱,因为 PowerShell 已经跨平台了 - 请参阅this GitHub issue

【讨论】:

  • 这将错过传递的参数,其中包含空格。 %* 实际上只是转储所有参数。
  • @TheIncorrigible1:否:如果您将它们正确引用到批处理文件中,它们将完整地传递。
  • @TheIncorrigible1:没有办法通过调用 shell 的规则正确传递参数,即cmd.exe。完成此操作后,该命令将按预期工作。
  • @TheIncorrigible1 运行test.cmd a "b c" d,其中test.cmd 的内容为powershell -File "%~dpn0.ps1" %*,将使用3 个参数调用test.ps1ab cd。您可以通过在 PowerShell 脚本中回显 $args 来验证这一点。
  • 适用于我的实例。我的示例中的额外引号是由于使用-Command 而不是-File,如答案中所述。谢谢!
【解决方案2】:

我想做类似的事情,但最近有点复杂,这里的答案和一些网站上的信息对我有很大帮助。在我的情况下,要从 cmd 传递的参数是可变数量的路径,通常带有空格,可能带有 $ 和 & - 并且参数将被喷溅,即字符串之间必须有逗号,否则脚本会解释它作为一个不同的论点。不管我做什么,我都会破坏一些东西。所以最后我将所有单独的条目连接到一个变量中,为 $ 和 & 引入了转义,并将其传递给中间脚本:

set a="%~1"
if [%1]==[] goto end
:loop
shift
set b="%~1"
if [%1]==[] goto execute
set a=%a% %b%
goto loop
:execute
set a=%a:&=`&%
set a=%a:$=`$%
powershell -file (fullpath)\intermediatescript.ps1 %a%
:end
exit

仅包含一行,调用主脚本:

& '(fullpath)\mainscript.ps1' -Path:$args

(我分享这个以防有人寻找与我类似的问题的解决方案,或者如果更聪明的人发现我的方法存在我迄今为止未能遇到的问题。)

【讨论】:

  • 试试echo %* - 可能会简化你的方法。
猜你喜欢
  • 2014-10-14
  • 1970-01-01
  • 2011-05-22
  • 2011-09-15
  • 2015-01-03
  • 1970-01-01
  • 2015-07-06
  • 2015-11-30
相关资源
最近更新 更多