Support for PipelineVariable in Advanced Function

Welcome Forums General PowerShell Q&A Support for PipelineVariable in Advanced Function

Viewing 1 reply thread
  • Author
    Posts
    • #185021
      Participant
      Topics: 2
      Replies: 3
      Points: 100
      Rank: Participant

      I mostly use PowerShell to automate tasks with VMware PowerCLI and I have recently started working on my first advanced functions. I created one that gets virtual machines that are inside a specific folder in vCenter. The main PowerCLI cmdlet used in this function is Get-VM so the output for Get-VM and my function is basically the same as far as I can tell. However, -PipelineVariable doesn't work for me as it does with Get-VM. When I run the following commands -which essentially do the same- the {$VM} is empty in the output of Get-SgVm (my function) but populated with the virtual machine name when using Get-Folder piped to Get-VM, everything else in the output is exactly the same.

      Get-SgVm -PipelineVariable VM | Get-NetworkAdapter | select {$VM},Name,NetworkName
      
      Get-Folder *RootFolder-001* | Get-VM -PipelineVariable VM | Get-NetworkAdapter | select {$VM},Name,NetworkName

      Here is the code of the function.

      
      Function Get-SgVm {
      
      [CmdletBinding()]
      param ([Parameter (Mandatory=$true,Position = 0)]
      [ValidateNotNullOrEmpty()]
      [int]$SGNumber,
      [switch]$NoRecursion,
      [switch]$Legacy)
      
      BEGIN {
      [string]$SGNumber = '{0:000}' -f $SGNumber
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Formatting SG Number to: $SGNumber"
      }
      
      PROCESS {
      
      If ($Legacy){
      $Folder = Get-Folder -Name (-join ('*RootFolder',$SGNumber,'*'))
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Folder found: $Folder"
      }
      
      Else {
      Write-Warning 'Legacy not selected.'
      $Folder = Get-Folder -Name (-join ('*RootFolder-',$SGNumber,'*'))
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Folder found: $Folder"
      } #If Legacy
      
      If ($NoRecursion){
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Getting VMs"
      $VMs = $Folder | Get-VM -NoRecursion
      Write-Warning 'NoRecursion switch used, getting VMs in root of SG folder only.'
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Getting VMs"
      $VMs = $Folder | Get-VM
      Write-Warning 'NoRecursion switch not used, getting all VMs in SG folder.'
      } #If Recursion
      
      If ($Folder -ne $null){
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] Working on folder: $Folder"
      }
      
      Else {
      Write-Warning 'No folder found. Check the switches used in the command.'
      } #If Folder
      
      If ($VMs -ne $null) {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] VM(s) found"
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] No VM(s) found"
      } #If VMS
      
      If (!$global:DefaultVIServer) {
      Throw 'Not connected to a vCenter server'
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] Writing output."
      Write-Output $VMs
      } #If vCenter connection
      
      } #Process
      
      END {}
      
      } #Function
    • #185339
      Participant
      Topics: 2
      Replies: 3
      Points: 100
      Rank: Participant

      After some testing I have figured out that by removing the BEGIN block altogether, -PipelineVariable works. I have updated the code with a Try/Catch construct so it looks a little different, however, I can tell for sure that even an empty BEGIN block would prevent the output to include the PipelineVariable value. I surely can't explain this behavior? Any ideas or thoughts? Thanks.

      Here is the latest function code:

      Function Get-SgVm {
      
      [CmdletBinding()]
      param (
      
      [Parameter (Mandatory=$true,Position = 0)]
      [ValidateNotNullOrEmpty()]
      [int]$SGNumber,
      [switch]$NoRecursion,
      [switch]$Legacy)
      
      Begin {
      [string]$SGNumber = '{0:000}' -f $SGNumber
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Formatting SG Number to: $SGNumber"
      
      } #Begin
      
      Process {
      
      Try {
      
      If ($Legacy){
      $Folder = Get-Folder -Name (-join ('*sysgrp',$SGNumber,'*'))
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Folder found: $Folder"
      }
      
      Else {
      Write-Warning 'Legacy not selected.'
      $Folder = Get-Folder -Name (-join ('*syrgrp-',$SGNumber,'*'))
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Folder found: $Folder"
      } #If Legacy
      
      If ($NoRecursion) {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Getting VMs"
      $VMs = $Folder | Get-VM -NoRecursion
      Write-Warning 'NoRecursion switch used, getting VMs in root of SG folder only.'
      Write-Output $VMs
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) BEGIN ] Getting VMs"
      $VMs = $Folder | Get-VM
      Write-Warning 'NoRecursion switch not used, getting all VMs in SG folder.'
      Write-Output $VMs
      } #If Recursion
      
      If ($Folder -ne $null) {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] Working on folder: $Folder"
      }
      
      Else {
      Write-Warning 'No folder found. Check the switches used in the command.'
      } #If Folder
      
      If ($VMs -ne $null) {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] VM(s) found"
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] No VM(s) found"
      } #If VMs
      
      } #Try
      
      Catch {
      
      If (!$global:DefaultVIServer) {
      Throw 'Not connected to a vCenter server'
      }
      
      Else {
      Write-Verbose "[$((Get-Date).TimeOfDay.ToString()) PROCESS] Writing output."
      Write-Output $VMs
      } #If vCenter connection
      
      } #Catch
      
      } #Process
      
      End {}
      
      } #Function

       

      Output with BEGIN block in function.

      Get-SgVm 1 -Legacy -NoRecursion | Get-NetworkAdapter | select {$VM},Name,NetworkName
      
      $VM Name NetworkName
      — —- ———–
      Network adapter 1 Isolated-VLAN23
      Network adapter 2 VLAN722
      Network adapter 1 Isolated-VLAN23
      Network adapter 2 VLAN722
      Network adapter 3 VLAN22
      Network adapter 1 Isolated-VLAN23
      Network adapter 2 CRSJO-VLAN722
      Network adapter 3 CRSJO-VLAN722
      Network adapter 1 Isolated-VLAN23
      Network adapter 2 VLAN722
      Network adapter 3 VLAN722

      Output without BEGIN block in function.

      Get-Folder *rootfolder001* | Get-VM -NoRecursion -PipelineVariable VM | Get-NetworkAdapter | select {$VM},Name,NetworkName
      
      VM Name NetworkName
      — —- ———–
      VOPPE-P001 Network adapter 1 Isolated-VLAN23
      VOPPE-P001 Network adapter 2 VLAN722
      VOPPE-MS001 Network adapter 1 Isolated-VLAN23
      VOPPE-MS001 Network adapter 2 VLAN722
      VOPPE-MS001 Network adapter 3 VLAN22
      VOPPE-TS001A Network adapter 1 Isolated-VLAN23
      VOPPE-TS001A Network adapter 2 VLAN722
      VOPPE-TS001A Network adapter 3 VLAN722
      VOPPE-TS001B Network adapter 1 Isolated-VLAN23
      VOPPE-TS001B Network adapter 2 VLAN722
      VOPPE-TS001B Network adapter 3 VLAN722

       

Viewing 1 reply thread
  • You must be logged in to reply to this topic.