首页 > 解决方案 > 将对象从一个脚本传递到另一个

问题描述

我在将数组成员传递给另一个脚本时遇到问题。我有一个从 CSV 提取的 VM 构建脚本,我最终得到一个带有 .Name、.CPU、.RAM、.IP 等的 $VM 对象。我想将该 VM 对象传递给另一个脚本(在新服务器内) 然后可以对其采取行动,但我无法这样做。我一直在测试正确的语法只是为了传递一个简单的数组,如下所示,但仍然没有成功:

CSV:

Name,NumCPU,MemoryGB,IPAddress
JLTest01,2,4,172.24.16.25

脚本1:

Function TestMe {
[CmdLetBinding()]
Param (
  [Parameter(Mandatory, Position=1)]
     [array]$arr
)

$arr | Out-GridView
}

TestMe

调用脚本:

$aVMs = Import-Csv -Path "PathToCsv"

foreach($VM in $aVMs) {  
   $command = "<path>\TestMe.ps1 " + "-arr $($VM)"
   Invoke-Expression $command
}

这会产生一个错误,似乎是在解析数组。错误指出:

术语“JLTest01”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。在 line:1 char:48 + ... \Desktop\TestMe.ps1 -arr @{Name=JLTest01; 数CPU ...

只是想弄清楚我到底做错了什么,以及将对象传递给第二个脚本需要做什么。

标签: powershell

解决方案


不要使用Invoke-Expression(这很少是正确的工具,出于安全原因通常应避免使用):

Import-Csv由执行的自定义对象输出的字符串化$($VM)不保留原始对象;它会导致类似于哈希表表示形式不适合编程处理,并且会破坏您传递给的命令行的语法Invoke-Expression

相反,只需直接调用您的脚本:

$aVMs = Import-Csv -Path "PathToCsv"

.\TestMe.ps1 -arr $aVMs

$aVMs请注意,鉴于您的-arr参数是数组类型的,我将整个传递给您的脚本。

如果您希望一个一个地处理对象,请坚持使用该foreach方法(但是您应该将$arr参数的类型声明为[pscustomobject]而不是[array]):

$aVMs = Import-Csv -Path "PathToCsv"

foreach ($VM in $aVMs) {
  .\TestMe.ps1 -arr $VMs
}

另一种选择是声明$arr为接受管道输入,process向您的脚本添加一个块,然后通过管道 $aVMs传输到您的脚本 ( $aVMs | .\TestMe.ps1)。


此外,不要在脚本中嵌套您从脚本中调用的同名函数.ps1,尤其是在没有传递参数的情况下;脚本可以直接声明参数,就像函数一样:

[CmdLetBinding()]
Param (
  [Parameter(Mandatory, Position=1)]
  [array]$arr
)

$arr | Out-GridView

推荐阅读