2017-08-20 4 views
1

J'ai créé une fonction avancée pour obtenir l'adresse MAC à partir d'une machine virtuelle exécutée sur VMware ESXi.La sortie de fonction avancée de PowerShell PipelineVariable ne fonctionne pas

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 {} 
} 

Jusqu'à présent, tout fonctionne parfaitement. Je peux l'utiliser de l'une des façons suivantes et obtenir des résultats.

Il accepte un seul ou un tableau de chaînes via le paramètre nommé ou comme entrée de pipeline.

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

La sortie est un [PSCustomObject] avec 2 propriétés, un nom et ClientId.

Maintenant, le problème commence lorsque je veux enchaîner le résultat à plusieurs autres cmdlets en utilisant le paramètre -PipelineVariable.

Normalement, je devrais pouvoir l'utiliser comme ceci:

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

Mais il ne me montre pas de résultats retour. Si je remplace le $pv par $_, il affiche le résultat correct, mais je ne peux pas utiliser cette variable automatique 2 ou 3 cmdlets plus loin dans la chaîne de pipeline.

Bien que je peux résoudre ce problème en utilisant le -OutVariable et/ou le diviser en plusieurs lignes. Je veux savoir pourquoi cela ne fonctionne pas, je veux savoir ce qui me manque ici.

+0

Quelle est votre version de PowerShell? –

+0

5.1.15063.483 sous Windows 10. – Adamar

Répondre

0

Je n'ai aucune expérience avec le paramètre -PipelineVariable. Alors, je pris cela comme une occasion d'en apprendre davantage sur le paramètre -PipelineVariable:

Parce que je n'ai pas facilement accès à des machines virtuelles non plus, je simulé la fonction comme suit:

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 ":","-"}} 
     } 
    } 
} 

Mais je ne suis pas en mesure de reproduire le problème:

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

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

Je me demande si cette fonction simulée fonctionne également pour vous.
Si oui, vous pouvez peut-être trouver les différences avec un objet VM réel. Connaissant PowerShell, je voudrais savoir si rien n'est sorti ou si rien n'est affiché. Alors qu'est-ce qui se passe si vous une seule propriété juste sortie:

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

Ou:

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

Est-ce retour d'une erreur "You cannot call a method on a null-valued expression."?

+0

Avec votre code modifié, cela fonctionne comme prévu. Mais avec le mien, non. Et c'est un oui sur votre dernière question, j'obtiens en effet l'erreur 'null-valued'. Autant que je sache, tout ce que je produis en sortie est un objet dans le pipeline, cela ne devrait donc pas importer ce que la cmdlet VMware donne, qui est aussi juste un objet. – Adamar

+0

La commande 'Get-VM' renvoie un 'UniversalVirtualMachineImpl' de' VMware.VimAutomation.ViCore.Impl.V1.Type de base Inventory.InventoryItemImpl'. – Adamar