Welcome › Forums › General PowerShell Q&A › Support for PipelineVariable in Advanced Function
- This topic has 1 reply, 1 voice, and was last updated 1 month, 1 week ago by
Participant.
-
AuthorPosts
-
-
October 26, 2019 at 6:13 am #185021
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
-
October 29, 2019 at 2:11 am #185339
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
-
-
AuthorPosts
- You must be logged in to reply to this topic.