【问题标题】:Passing array to another script with Invoke-Command使用 Invoke-Command 将数组传递给另一个脚本
【发布时间】:2013-07-08 19:11:43
【问题描述】:

我一直在努力解决这个问题。我已经看过其他文章并尝试了所有方法,但我没有得到任何结果。我正在尝试将数组作为参数传递给另一个 PS 脚本。这是我正在尝试的:

$IPArray = Get-Content C:\ListofIps.txt
Invoke-Command -Computername $server -Credential $cred -FilePath "C:\script.ps1" -ArgumentList (,$IPArray)

$IPArray 中的 5 个值没有传递给我调用的脚本。

在此先感谢各位,非常感谢您提供的任何帮助...

【问题讨论】:

  • 为什么在 $IPArray 之前有一个逗号,为什么要把它放在括号里?如果您只想将 $IPArray 作为参数列表传递,请使用 -ArgumentList $IPArray
  • 感谢您的快速回复,阿迪。根据this thread,-ArgumentList 需要括号和逗号才能将参数视为数组。然而,我尝试了两种方式,但都没有成功。
  • script.ps1 是否有一个 param() 语句来接受参数?尝试通过将以下内容放入 $server 上的 test.ps1 文件中来进行测试: param([string[]$IPs) $IPS |写输出这至少应该告诉你参数是否被目标脚本正确传递和接受。
  • 看起来就是这样,JBSmith!我之前尝试过 param 语句,但没有意识到它必须是第二个脚本中的第一个可执行行。这让我得到了我需要的东西,但我什至必须将 $IPArray 作为 -ArgumentType 传递吗?调用 test.ps1 脚本时,它不应该作为全局变量在范围内吗?
  • $IPArray 在您当前的本地会话中处于全局范围内。但是当您运行 Invoke-Command 时,您将在远程计算机上启动一个新的、全新的会话。那台计算机中没有本地会话中的任何本地变量、函数、模块等。在 powershell 版本 3 中,有一个名为 using 的新变量“范围”,可以将本地变量传递给远程会话。因此,您可以像这样在脚本中指定变量:“$using:IPArray”。但在版本 2 中,您必须使用 -ArgumentList 将本地变量获取到远程机器。

标签: arrays powershell invoke-command


【解决方案1】:

用途:

... -ArgumentList (,$IPArray)

因为ArgumentList 参数需要一个数组,您已经正确指出您需要将该数组包装在另一个数组中。但是,在这种情况下(指定参数值)的正确语法是使用分组表达式() 创建嵌套数组。

【讨论】:

  • 如果使用@($IPArray),则第一个逗号不是必需的。
  • @() 对数组没有任何作用。也就是说,如果@() 的内容是一个标量,则该标量被放入数组中,但如果内容已经是一个数组,则该数组不会被包装在另一个数组中。
  • 有趣,我不知道。谢谢。
【解决方案2】:

这是一个老问题,但我将在答案上重复@keith-hill——在数组声明的开头添加一个逗号(即使包含现有数组)。

这很愚蠢,但我再次回答,因为我尝试了所有替代方案,这是唯一有效的方法 - 即使使用 PowerShell 3.0+。您可以将#require 用于至少从 v3.0+ 开始的任何内容,但除非您按照@keith-hill 的建议进行操作,否则什么都不会起作用——即使它是一个数组,并且参数是一个数组,在这种情况下 PS 很烂(我喜欢PS)...照他说的做(发帖没有用,很抱歉,但有效的答案更好): \ ... -ArgumentList (,$IPArray)

这没有意义,但它有效。把炸弹交给 PS 团队,但如果我没有这样做,我的剧本将是无效的。我已经成为“脚本专家”......所以你去吧。

【讨论】:

  • 真的很想编辑它,但老实说,你的修复不起作用......也许对你来说,但不是对其他人。不过,我很想听听您的问题...
  • 这并不愚蠢。发生的事情是,-ArgumentList 默认情况下 采用一个数组并将项目分散到调用命令中的参数:Invoke-Command -ScriptBlock { param($x, $y, $z) ... } -ArgumentList (1, 2, 3) 将 $x 设置为 1,$y 设置为 2 $y,$ z 到 3。所以,-ArgumentList 已经有特殊的数组处理;它基本上是如何工作的。当您传入自己的数组时,它无法区分您的数组和 e.g. (1, 2, 3),因此它会获取您的数组项并分发它们。 (, $x) 语法使它得到一个包含 1 个元素的数组,并且该元素 是你的数组
【解决方案3】:

如果您只是想传递一个数组,您可以将 $args 变量本身视为远程命令中的数组,您会得到与将其传递为 (, $IPArray) 的结果相同的结果,然后在脚本块为 $args[0]。我没有测试这是否适用于多个数组。

也就是说,

$MyScriptBlock = { $args | % { Do-Stuff -Thing $PSItem } }
Invoke-Command -Session $MySession -ScriptBlock $MyScriptBlock -ArgumentList $IPArray

将返回与

相同的值
$MyScriptBlock = { $args[0] | % { Do-Stuff -Thing $PSItem } }
Invoke-Command -Session $MySession -ScriptBlock $MyScriptBlock -ArgumentList (,$IPArray)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    相关资源
    最近更新 更多