PowerShell Not Your Father’s Command Line Part 8 of 31: Won’t You Take Me To Functiontown?

Yesterday, Matt blogged about a basic PowerShell functions. I also have blogged in the past of some helpful functions that work with some of the PowerShell-specific providers. The code for those is fairly simple. However, functions aren’t always that simple; you can also write an advanced function, which runs similar to cmdlets.

Since advanced functions can be a large topic and some of this stuff overlaps with cmdlets, I am covering only a few of the topics in today’s posts.

Runtime Life Cycle
There are three phases that a function can go through:

  • Begin
  • Process
  • End

In PowerShell, Begin is run once, at the beginning of the function, before any pipeline objects are processed. Process is run for each object that is piped to that function. The automatic variable $_ is used for the individual pipeline object that is being processed during the Process phase. Once Process is finished, then End is run. Like Begin, End is run only once per function call.

If these keywords are left out, the advanced function’s normal processing behavior is treated like End.

Here is an example that uses all of these phases:

function Convert-FahrenheitToCelsius{
   begin{
      "Converting Fahrenheit input to Celsius:"
   }
   process {
      $degreesC = ($_ - 32)/1.8 
      "$_  degrees F = $degreesC degrees C"
   }
   end {
      "Done converting the input to Celsius"
   }
}

If I run the following command, I should get the following output.

Command

80, 32, 0  | Convert-FahrenheitToCelsius

Output

Converting Fahrenheit input to Celsius:
80  degrees F = 26.6666666666667 degrees C
32  degrees F = 0 degrees C
0  degrees F = -17.7777777777778 degrees C
Done converting the input to Celsius

Now since begin and end are only displaying strings and not handling the conversion, we can eliminate them. This would work just fine:

function Convert-FahrenheitToCelsius{
   process {
      $degreesC = ($_ - 32)/1.8 
      "$_  degrees F = $degreesC degrees C"
   }
}

Since the process keyword is present, the function will treat each of the pipeline objects individually. But what would it look like if we left off the process keyword?

function Convert-FahrenheitToCelsius{
   $degreesC = ($_ - 32)/1.8 
   "$_  degrees F = $degreesC degrees C"
}

The output for the sample command would be:

  degrees F = -17.7777777777778 degrees C

Notice that it didn’t treat the pipeline objects individually. This is probably not what you want, so if you’re going to pipe in objects that need to be treated individually, then the process keyword is needed.

This should give you an idea on the three phases that a function can go through. However, if you need more information on the runtime life cycle, you can find it by running:

Get-Help about_functions

You can also find out more about the Begin, Process, and End methods – in addition to many methids for confirmation, writing, error handling, and others – available to advanced functions by running:

Get-Help about_functions_advanced_methods

In the next post, later today, we will look at a few agruments of the Parameter attribute and mention the CmdletBinding attribute.

2 thoughts on “PowerShell Not Your Father’s Command Line Part 8 of 31: Won’t You Take Me To Functiontown?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>