VMware Cloud Community
markdjones82
Expert
Expert
Jump to solution

Function parameter question

Ok I have a function where I am trying to go through a bunch of vmhosts, but when i pass say get-vmhost for all hosts and print out $vmobject it only lists the first object.  What am I missing on the parameter part?

function host_info {

param (

  [CmdletBinding()]

  [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$True)]

  $VMObject

  )

     $vmobject

}

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
Reply
0 Kudos
1 Solution

Accepted Solutions
mattboren
Expert
Expert
Jump to solution

Hello, markdjones82-

As for the Parameter() portion of the $VMHostObject parameter, you are not missing anything that is causing this behavior.  The "missing" thing is the Process{ } scriptblock in the body of the function.  To get this to behave like you are wanting, you need to add such a scriptblock.  See the example below that is based on your initial function:  it writes verbose messages in each of the Begin, Process, and End scriptblocks.  This is so that you can see the difference when using the function with either direct value passing (to a param), or with taking values from the pipeline.

function Get-VMHostInfo {
    [CmdletBinding()]
   
Param (
        [Parameter(Mandatory
=$true,ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$true)]
       
$VMHostObject
    )
   
begin {Write-Verbose -Verbose "starting; this 'begin' scriptblock only runs one time, and, if a pipelining example, this is before any param variables have values (see:  the value of `$VMHostObject is '$VMHostObject')"}
   
process {
       
Write-Verbose -Verbose "in the process scriptblock, either once (non-pipeline example) or for each value passed in a pipelining example"
       
$VMHostObject
    }
   
end {Write-Verbose -Verbose "in the 'end' scriptblock, and only once"}
}

When taking values from the pipeline, the function is an "advanced function" as PowerShell deems it, and advanced functions behave a bit differently.  To see the differences, invoke this function in the following ways, and the verbose messages along with the output objects should illuminate.

## non-pipeline example:  should have just three verbose messages
Get-VMHostInfo -VMHostObject (Get-VMHost myhosts.*)

## pipeline example:  should have larger number of verbose messages:
#
#   one for begin{}, one for every VMHost in the pipeline, and one for end{}
##   and, the value for VMHostObject in the verbose message in the begin{} should be empty
Get-VMHost myhosts.* | Get-VMHostInfo

And, suggestion on the function naming:  use the PowerShell standard of Verb-Noun, for consistency, discoverability, etc.  Also, you can read more about the function input processing methods in the help topic for about_Functions_Advanced_Methods (Get-Help about_Functions_Advanced_Methods).

How does that do for you?

View solution in original post

Reply
0 Kudos
4 Replies
mattboren
Expert
Expert
Jump to solution

Hello, markdjones82-

As for the Parameter() portion of the $VMHostObject parameter, you are not missing anything that is causing this behavior.  The "missing" thing is the Process{ } scriptblock in the body of the function.  To get this to behave like you are wanting, you need to add such a scriptblock.  See the example below that is based on your initial function:  it writes verbose messages in each of the Begin, Process, and End scriptblocks.  This is so that you can see the difference when using the function with either direct value passing (to a param), or with taking values from the pipeline.

function Get-VMHostInfo {
    [CmdletBinding()]
   
Param (
        [Parameter(Mandatory
=$true,ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$true)]
       
$VMHostObject
    )
   
begin {Write-Verbose -Verbose "starting; this 'begin' scriptblock only runs one time, and, if a pipelining example, this is before any param variables have values (see:  the value of `$VMHostObject is '$VMHostObject')"}
   
process {
       
Write-Verbose -Verbose "in the process scriptblock, either once (non-pipeline example) or for each value passed in a pipelining example"
       
$VMHostObject
    }
   
end {Write-Verbose -Verbose "in the 'end' scriptblock, and only once"}
}

When taking values from the pipeline, the function is an "advanced function" as PowerShell deems it, and advanced functions behave a bit differently.  To see the differences, invoke this function in the following ways, and the verbose messages along with the output objects should illuminate.

## non-pipeline example:  should have just three verbose messages
Get-VMHostInfo -VMHostObject (Get-VMHost myhosts.*)

## pipeline example:  should have larger number of verbose messages:
#
#   one for begin{}, one for every VMHost in the pipeline, and one for end{}
##   and, the value for VMHostObject in the verbose message in the begin{} should be empty
Get-VMHost myhosts.* | Get-VMHostInfo

And, suggestion on the function naming:  use the PowerShell standard of Verb-Noun, for consistency, discoverability, etc.  Also, you can read more about the function input processing methods in the help topic for about_Functions_Advanced_Methods (Get-Help about_Functions_Advanced_Methods).

How does that do for you?

Reply
0 Kudos
markdjones82
Expert
Expert
Jump to solution

Ah I see, so basically without the begin and process my code is running in "begin"?

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

Hello-

Almost, and that is a point that I should have included:  without specifying any of those begin-, process-, or end scriptblocks, the code in the body of the function is effectively running in an end scriptblock.  You should be able to verify that behavior by updating the code in the body of the function from your original post to be in an end {} scriptblock -- it should give the same behavior as did your original code.  Does it?

Reply
0 Kudos
markdjones82
Expert
Expert
Jump to solution

That did the trick, i was actually just putting a portion of my code in here as an example.  Thanks for the help!

http://www.twitter.com/markdjones82 | http://nutzandbolts.wordpress.com
Reply
0 Kudos