两次不能执行相同的powershell函数,给出错误

时间:2012-01-27 04:08:24

标签: powershell

我对powershell很新,我基本上编写了一个脚本,它根据主列在几个.csv文件上执行连接。我在这里使用Join-Collections脚本:http://poshcode.org/1461

由于我需要组合5个.csv文件,我需要运行此功能4次。

在第一次运行时,它运行正常,但是然后尝试再次运行该函数会给出'没有指定cmd-let'错误的对象。

在尝试调试时,我实际上已经复制并粘贴了该行,只更改了变量名以生成新变量。

我必须做一些根本错误的事......

$SumFile = "VMSummary.csv"
$MemFile = "VMMemory.csv"
$ProcFile = "VMProcessor.csv"
$OSFile = "VMOS.csv"
$NicFile = "VMNics.csv"

$SumFileCSV = Import-Csv $SumFile | Select VMElementName,GuestOS,Heartbeat,MemoryUsage,IpAddress
$MemFileCSV = Import-Csv $MemFile | Select VMElementName,Reservation
$ProcFileCSV = Import-Csv $ProcFile
$OSFileCSV = Import-Csv $OSFile
$NicFileCSV = Import-Csv $NicFile

$JoinColumn = "VMElementName"

function Join-Collections {
PARAM(
   $FirstCollection
,  [string]$FirstJoinColumn
,  $SecondCollection
,  [string]$SecondJoinColumn=$FirstJoinColumn
)
PROCESS {
   $ErrorActionPreference = "Inquire"
   foreach($first in $FirstCollection) {
      $SecondCollection | Where{ $_."$SecondJoinColumn" -eq $first."$FirstJoinColumn" } | Join-Object $first
   }
}
BEGIN {
   function Join-Object {
   Param(
      [Parameter(Position=0)]
      $First
   ,
      [Parameter(ValueFromPipeline=$true)]
      $Second
   )
   BEGIN {
      [string[]] $p1 = $First | gm -type Properties | select -expand Name
   }
   Process {
      $Output = $First | Select $p1
      foreach($p in $Second | gm -type Properties | Where { $p1 -notcontains $_.Name } | select -expand Name) {
         Add-Member -in $Output -type NoteProperty -name $p -value $Second."$p"
      }
      $Output
   }
   }
}
}

$Temp = Join-Collections $SumFileCSV $JoinColumn $MemFileCSV $JoinColumn

$Temp

##BREAKS HERE
$Temp2 = Join-Collections $SumFileCSV $JoinColumn $MemFileCSV $JoinColumn

更新

它出现以下错误:

No object has been specified to the get-member cmdlet
+ foreach($p) in $Second | gm <<<<  -type Properties | Where { $p1 -notcontains     $_.Name } | select -expand Name) 

csv数据非常简单。当我在临时打印之前打印出$ Temp时,它会吐出来:

GuestOS       : Windows Server (R) 2008 Standard
Heartbeat     : OK
IpAddress     : 192.168.48.92
MemoryUsage   : 1024
VMElementName : VM015
Reservation   : 1024

GuestOS       : Windows Server (R) 2008 Standard
Heartbeat     : OK
IpAddress     : 192.168.48.151
MemoryUsage   : 1028
VMElementName : VM053
Reservation   : 1028

GuestOS       : Windows Server (R) 2008 Standard
Heartbeat     : OK
IpAddress     : 192.168.48.214
MemoryUsage   : 3084
VMElementName : VM065
Reservation   : 3084

GuestOS       : 
Heartbeat     : 
IpAddress     : 
MemoryUsage   : 
VMElementName : VM074
Reservation   : 1024

GuestOS       : Windows Server 2008 R2 Standard
Heartbeat     : OK
IpAddress     : 192.168.48.32
MemoryUsage   : 3072
VMElementName : VM088
Reservation   : 3072

GuestOS       : Windows Server (R) 2008 Enterprise
Heartbeat     : OK
IpAddress     : 192.168.48.81
MemoryUsage   : 3084
VMElementName : VM090
Reservation   : 3084

GuestOS       : Windows Server 2008 R2 Enterprise
Heartbeat     : OK
IpAddress     : 192.168.48.82
MemoryUsage   : 5120
VMElementName : VM106
Reservation   : 5120

其余的.csv数据也是同样的东西 - 只是不同服务器上的统计数据。

理想情况下,我想做的是:

$Temp = Join-Collections $SumFileCSV $JoinColumn $MemFileCSV $JoinColumn

$Temp = Join-Collections $Temp $JoinColumn $ProcFileCSV $JoinColumn

$Temp = Join-Collections $Temp $JoinColumn $OSFileCSV $JoinColumn

$Temp = Join-Collections $Temp $JoinColumn $NicFileCSV $JoinColumn | Export-Csv "VMJoined.csv" -NoTypeInformation -UseCulture

1 个答案:

答案 0 :(得分:1)

此代码在Powershell v3 CTP 2上运行良好(这可能是@manojlds正在使用的)。但是在Powershell V2中,$second函数的参数Join-Object在第二次调用Join-Collections时不受约束。通过将以下行添加到Join-Object函数中的过程块:

,可以轻松验证这一点
$psboundparameters | out-host

您会注意到,第一次调用Join-Collections时,两个参数(Join-Object都被绑定),但第二次$second不再受约束。

目前还不清楚导致此行为的原因,但由于它似乎在Powershell V3中运行,我猜它是一个错误。

要使函数在Powershell V2中有效,可以通过替换以下行来显式绑定参数:

$SecondCollection | Where{ $_."$SecondJoinColumn" -eq $first."$FirstJoinColumn" } | Join-Object $first

这一行:

$SecondCollection | Where{ $_."$SecondJoinColumn" -eq $first."$FirstJoinColumn" } | %{Join-Object -first $first -second $_}