【问题标题】:How to use the call operator to pass parameters to another PowerShell script如何使用调用运算符将​​参数传递给另一个 PowerShell 脚本
【发布时间】:2020-01-30 17:03:30
【问题描述】:

我有一个 PowerShell 脚本,它将参数收集到一个数组中,然后尝试使用这些参数调用可执行文件。

param(
    [String] $FileName,
    [Parameter(ValueFromRemainingArguments=$true)][String[]] $Arguments
)

& $FileName $Arguments

这在调用简单的可执行文件时效果很好,但在尝试调用另一个需要多个参数的 PowerShell 脚本时会抛出错误。

例外: 无法处理参数“a”的参数转换。无法转换价值 键入 System.String。

param(
    [parameter(mandatory = $true)][string]$a,
    [parameter(mandatory = $true)][string]$b,
    [parameter(mandatory = $true)][string]$c,
    [parameter(mandatory = $true)][string]$d
)

Write-Output ($a + " - " + $b + " - "+ $c + " - "+ $d)

参数的数量是可变的。

我的猜测是调用操作符,因为被调用文件是一个 PowerShell 脚本,它试图将数组作为对象传递,而不是拆分参数。 我不一定要诉诸 Invoke-Expression,因为用户提供了一些参数,这可能会带来风险

编辑: 我最终做了类似于 Jimmy Robitaille 建议的事情。

$Command = "& $FileName"
foreach ($Arg in $Arguments) {
    $Arg = $Arg.Replace("`"", "```"")
    if ($Arg.Contains(' ') -or $Arg.Contains(';')) {
        $Command += " `"$Arg`""
    }
    else {
        $Command += " $Arg"
    }
}
Invoke-Expression $Command

这是我自己创建参数字符串并执行它。我从参数中转义了引号,并将包含空格或分号的参数括起来。

【问题讨论】:

  • 你可能想看看$PSBoundParameters >>> PSBoundParameters - PowerShell - SS64.com - ss64.com/ps/psboundparameters.html ValueFromRemainingArguments参数属性,并在$Args自动变量。
  • 使用调用运算符&,PowerShell 期望参数及其对应的参数用空格分隔。参数-参数对周围不应有引号。
  • @Lee_Dailey 我看了那些,但我看不出它们会有什么帮助。调用者脚本可以使用它们来收集要传递给被调用脚本的参数,但这并不能解决问题。
  • @Krajla - 啊!我误解了你的意图。 [blush] 我看到你找到了一种解决方法......很好! [咧嘴]

标签: powershell


【解决方案1】:

您可以尝试使用字符串数组的索引而不是传递数组本身,如下所示:

& $FileName $Arguments[0] $Arguments[1] $Arguments[2] $arguments[3]

请注意,如果传递的参数数量少于 4 个,脚本仍然会失败,并且任何超过第 4 个的参数都将被忽略。一些验证也会有所帮助,但这至少可以让您将参数传递给其他脚本而不会出错。

编辑:

在澄清之后,不诉诸调用命令,我能想到的唯一方法是做这样的事情:

powershell.exe `"$FileName`" $($Arguments -join ' ')

您可以尝试解析 FileName 并检查它是否为 PS1,然后使用呼叫运算符或启动 powershell。

【讨论】:

  • 参数个数是可变的,我会在问题中添加澄清。
  • 我编辑了我的答案,如果我误解了什么,请随时告诉我。
  • 这可行,但不幸的是为命令注入留下了空间。如果我然后估算 '-FileName ".\Test.ps1" a b c "d;cat .\Test.ps1"' 输出将是。 a - b - c - d 参数([参数(强制 = $true)][字符串]$a,[参数(强制 = $true)][字符串]$b,[参数(强制 = $true)][字符串]$c, [parameter(mandatory = $true)][string]$d ) 写输出 ($a + " - " + $b + " - "+ $c + " - "+ $d)
  • 但如果这是使其工作的唯一方法,我将对参数实施黑名单。
  • 调用运算符不解析字符串并进行一些特殊处理,例如在需要的地方添加引号,据我了解,代码注入不适用于调用运算符的原因与为什么如果参数的数量是可变的,您尝试做的将不起作用。 “powershell”命令至少还具有在子范围内运行其他脚本的优势,但代码注入确实是可能的。
猜你喜欢
  • 2012-04-13
  • 2016-10-26
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 2011-08-01
  • 2020-04-04
相关资源
最近更新 更多