【问题标题】:Powershell: Pass multiple values (with spaces) to an argumentPowershell:将多个值(带空格)传递给参数
【发布时间】:2017-05-07 12:41:20
【问题描述】:

我有一个使用多个参数的脚本,其中一些包含空格。该脚本是从另一个脚本调用的,因此我将参数从带有调用脚本的变量传递给它。

调用脚本:

$script = "C:\Path\script.ps1"
$arg1 = "SomeValue"
$arg2 = "1234"
$arg3 = @("Value1","Some Value","Value 2")
$arg4 = $true
Invoke-Command $script -Arg1 $arg1 -Arg2 $arg2 -Arg3 $arg3 -Arg4 $arg4

调用的脚本如下所示:

param (
[Parameter(Mandatory=$false,Position=0)]
[String]$arg1,
[Parameter(Mandatory=$false,Position=1)]
[String]$arg2,
[Parameter(Mandatory=$false,Position=2)]
[array]$arg3,
[Parameter(Mandatory=$false,Position=3)]
[bool]$arg4
)

# Do stuff with the arguments

当我调用脚本时,出现以下错误:

"A positional parameter cannot be found that accepts argument 'Some'."

我还在 powershell 窗口中手动调用了脚本(绕过调用脚本),如下所示:

powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 @("Value1","Some Value","Value 2") -Arg4 $true

powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1","Some Value","Value 2" -Arg4 $true

powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1","SomeValue","Value2" -Arg4 $true

powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1,SomeValue,Value2" -Arg4 $true

这些变体都不起作用。我还通过将 Arg3 值更改为 (,$args) 来尝试找到 here 的想法,但这不起作用。我还更改了 here 找到的参数类型,但这也没有用。

目标是能够通过参数/参数将多个变量(一些带有空格)传递给脚本。

EDIT 12/22/16:目标包括从快捷方式/键入命令传递相同的信息。例如,我的调用脚本在注册表中创建了一个 RunOnce 条目来引用被调用的脚本,并将参数放入调用中,就像上面的手动示例一样。它们都不起作用。

Set-ItemProperty $RegROPath "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass $scriptPath $argumentList" -type String

【问题讨论】:

  • powershell.exe -ExecutionPolicy bypass --% "C:\Path\script.ps1 -Arg1 \"SomeValue\" -Arg2 \"1234\" -Arg3 \"Value1\",\"Some Value\",\"Value 2\" -Arg4 $true"
  • 您好 PetSerAl,我将以编程方式构建它,因此值需要来自 splatted 数组。
  • 可以的。您只需要在任何地方应用适当的转义即可。
  • 所以我需要通过转义在数组元素中包含引号?我不明白。

标签: powershell


【解决方案1】:

Invoke-Command 替换为&.

如果您只想输出,请使用&,如果您希望它在当前上下文中运行(例如,保留所有变量集),请使用.

Get-Help about_Scripts 了解更多详情(或阅读online version here

编辑:忘了说,不是你的脚本引发了这个错误,而是Invoke-Command。如果您绝对必须使用Invoke-Command,则需要(例如远程运行)将参数作为参数ArgumentList 传递,如下所示:

$script = "C:\Path\script.ps1"
$argumentList = @(
    '-arg1 "SomeValue"',
    '-arg2 1234',
    '-arg3 @("Value1","Some Value","Value 2")',
    '-arg4 $true'
)
Invoke-Command -FilePath $script -ArgumentList $argumentList

编辑 2:

我会尽快尝试您的建议。一个问题,如果我需要添加一个条件参数怎么办?目前,我使用 $argumentlist += ("arg5", "value") 将参数添加到列表中。其中一些是有条件的:if ($bool) {$argumentlist += ("arg5", "value")}。在你的例子中有没有办法做到这一点?

是的,您可以,示例中的$argumentList 变量与其他数组一样是一个数组。它可以一次性定义,也可以定义为空并稍后添加,或者任意混合。

例子

$argumentList = @(
    '-arg1 "SomeValue"',
    '-arg2 1234',
    '-arg3 @("Value1","Some Value","Value 2")',
    '-arg4 $true'
)
if ($bool) {
    $argumentList += '-arg5 "value"'
}
Invoke-Command -FilePath $script -ArgumentList $argumentList

但同样,除非您在远程计算机或 PSSession 上运行该命令,否则您应该使用 & 或点源 (.)。您仍然可以使用 splatting (about_Splatting) 有条件地添加参数

例子

$scriptParamsSplat = @{
    arg1 = "SomeValue"
    arg2 = 1234
    arg3 = @("Value1","Some Value","Value 2")
    arg4 = $true
}
if ($bool) {
    $scriptParamsSplat.arg5 = "value"
}
& 'C:\Path\To\script.ps1' @scriptParamsSplat

【讨论】:

  • 我会尽快尝试您的建议。一个问题,如果我需要添加一个条件参数怎么办?目前,我使用 $argumentlist += ("arg5", "value") 将参数添加到列表中。其中一些是有条件的:if ($bool) {$argumentlist += ("arg5", "value")}。在你的例子中有没有办法做到这一点?
  • 带有 splatted 参数的脚本调用失败,并显示“无法处理参数 'Arg3' 上的参数转换。无法将值转换为 System.String 类型”。此外,调用脚本会创建对脚本的 RunOnce 调用,以在重新启动后持续存在。当再次调用该脚本时,我得到相同的错误(请参阅我原始帖子中的手动示例)。如何将一组值(带空格)作为 RunOnce/shortcut/Scheduled Task 的参数?
  • powershell -ExecutionPolicy Bypass -NoProfile -Command "& 'pathtoscript' -Arg1 @(1, 2, 3)"
  • 至于 splat 失败,请确保您没有用引号括住数组定义。
  • 我的参数声明看起来和你的一模一样。唯一的引号在字符串周围。
猜你喜欢
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2016-01-19
  • 2022-11-24
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多