2017-08-20 57 views
1

我創建了一個高級函數來從運行在VMware ESXi上的VM獲取MAC地址。PowerShell高級功能輸出PipelineVariable不起作用

function Get-MacFromVm { 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    Param(
     # The name of the VM of which we want to obtain the mac address. 
     [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true, 
        ValueFromPipelineByPropertyName=$true)] 
     [string[]] 
     $Name 
    ) 

    Begin {} 
    Process { 
     foreach ($item in $Name) { 
      if ($PSCmdlet.ShouldProcess($item, "Getting the mac address")) { 
       Get-VM $item -PipelineVariable vm | 
        Get-NetworkAdapter | 
        Select-Object @{n="Name"; e={$vm.Name}}, 
         @{n="ClientId"; e={$_.MacAddress -replace ":","-"}} 
      } 
     } 
    } 
    End {} 
} 

到目前爲止,一切都很完美。 我可以通過以下任何方式使用它並獲得結果。

它通過命名參數或流水線輸入接受單個或字符串數​​組。

Get-MacFromVm -Name "playground" 
Get-MacFromVm -Name "playground", "DC01" 
"playground", "DC01" | Get-MacFromVm 

的輸出是一個與[PSCustomObject] 2屬性,名稱和所述客戶端Id。

現在,當我想通過使用參數-PipelineVariable將結果鏈接到多個其他cmdlet時,問題就開始了。

通常情況下,我應該能夠使用它像這樣:

Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv} 

但它不告訴我任何結果回來。如果我將$pv替換爲$_,它確實顯示了正確的結果,但我無法在管道鏈中使用自動變量2或3的更小命令。

雖然我可以通過使用-OutVariable和/或將其分成多行來解決此問題。 我想知道爲什麼這不起作用,我想知道我在這裏錯過了什麼。

+0

什麼是您的PowerShell版本? –

+0

5.1.15063.483在Windows 10上。 – Adamar

回答

0

我沒有-PipelineVariable參數的經驗。於是,我把這個作爲一個機會來了解-PipelineVariable參數:

因爲我不容易接觸到虛擬機或者,我模擬的功能如下:

Function Get-MacFromVm { 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    Param(
     [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true, 
        ValueFromPipelineByPropertyName=$true)] 
     [string[]] 
     $Name 
    ) 
    Function MacAddress {(1..4 | ForEach {'{0:x2}' -f (Get-Random -Min 0 -Max 255)}) -Join ":"} 
    Function Get-VM {[cmdletbinding()] Param ($Name) [pscustomobject]@{Name = $Name; MacAddress = (MacAddress)}} 
    ForEach ($Item in $Name) { 
     If ($PSCmdlet.ShouldProcess($Item, "Getting the mac address")) { 
      Get-VM $item -PipelineVariable vm | 
      Select-Object @{n="Name"; e={$vm.Name}}, @{n="ClientId"; e={$_.MacAddress -replace ":","-"}} 
     } 
    } 
} 

但我不能重現問題:

PS C:\> Get-MacFromVm -Name "playground", "DC01" -PipelineVariable pv | % {$pv} 

Name  ClientId 
----  -------- 
playground 3c-23-55-c4 
DC01  4f-38-42-a7 

所以我不知道這個模擬函數是否也適用於你。
如果是,也許你可以找到與真正的VM對象的差異。

瞭解PowerShell,我會質疑是否沒有輸出或沒有顯示。

Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv.Name} 

或者:

Get-MacFromVm -Name "playground" -PipelineVariable pv | % {$pv.GetType()} 

是否能返回 「You cannot call a method on a null-valued expression.」 錯誤,所以如果你只輸出一個屬性會發生什麼?

+0

使用修改的代碼,它按預期工作。但用我自己的事實並非如此。 這是對你最後一個問題是肯定的,我確實得到了'空值'的錯誤。 據我所知,我輸出的所有東西都是一個進入管道的對象,所以它應該與VMware cmdlet提供的內容無關,這也僅僅是一個對象。 – Adamar

+0

'Get-VM'命令返回'VMware.VimAutomation.ViCore.Impl.V1的'UniversalVirtualMachineImpl'。Inventory.InventoryItemImpl'基本類型。 – Adamar