Не может выполнить одну и ту же функцию powershell дважды, выдает ошибку - PullRequest
0 голосов
/ 27 января 2012

Я довольно новичок в 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

UPDATE

Выдает следующую ошибку:

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 Ответ

1 голос
/ 27 января 2012

Этот код отлично работает на 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 $_}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...