4 Replies Latest reply on Oct 14, 2015 2:05 PM by markdjones82

    Function parameter question

    markdjones82 Expert

      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

      }

        • 1. Re: Function parameter question
          mattboren Master
          vExpert

          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?

          • 2. Re: Function parameter question
            markdjones82 Expert

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

            • 3. Re: Function parameter question
              mattboren Master
              vExpert

              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?

              • 4. Re: Function parameter question
                markdjones82 Expert

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