If you want to take your PowerShell function writing skills to the next level, consider implementing Begin, Process, and End blocks. These input processing methods enable your functions to process pipeline input and multiple parameter values.

In this article, you will learn the basic syntax of PowerShell Begin, Process, and End blocks and how to implement them in a function.

Understanding PowerShell Input Processing

The three components for handling input processing in advanced PowerShell functions are the Begin, Process, and End blocks. When writing advanced functions, these blocks add advanced capabilities for handling input, especially from the pipeline. However, you are not required to include any of these blocks in your functions.

Let’s review each block and its purpose in the following sections.

Begin

PowerShell executes the Begin block first in a function. This block performs any setup action used in the rest of the function, such as defining variables or setting up resources. For example, if you need to connect to a database, you configure the connection in the Begin block. PowerShell runs the Begin block code only once for each instance of the function in a pipeline. This block is optional.

Process

The Process block is the main component of your function. This block contains the function’s primary logic in completing its tasks. PowerShell executes the Process block more than once, depending on the input objects in the pipeline or the configuration of the function’s parameters (more on this later).

A Process block is required if you want a function to accept pipeline input. If the function does not have a Process block, then pipeline input processing will fail. The function will only execute once, regardless of the input.

End

PowerShell executes the End block last in a function. This block provides post-processing actions for the function, like closing a database connection opened in the Begin block. Like the Begin block, the End block is optional in a function and only executes once.

Input Processing Notes

The following points outline some additional details on the various input processing blocks.

  • You can use a Process block without defining a Begin or End block.
  • When using all three blocks, all PowerShell code must be inside one of the blocks.
  • These blocks are available to functions whether or not you use the CmdletBinding attribute.

Reviewing Syntax

The following code sample shows the basic syntax of Begin, Process, and End blocks. In this example, the function name is Show-BeginProcessEnd and uses the CmdletBinding attribute. The function currently has no parameters, and each block contains an output statement showing which block PowerShell is executing.

function Show-BeginProcessEnd {
    [CmdletBinding()]
    param()
    Begin {"This is the Begin block."}
    Process {"This is the Process block."}
    End {"This is the End block."}
}

The following screenshot shows the output of calling the function. Note that each statement is currently only printed to the console one time.

powershell begin process end output example
Output of basic Begin, Process, and End blocks

Adding Pipeline Parameter Input

Let’s add input processing by adding an integer parameter named $Item. This parameter is mandatory and accepts values from the pipeline. You will see how the parameter takes pipeline input in an upcoming example.

Next, change the code in the Process block to show which $Item the block is currently processing. Here is the updated function.

function Show-BeginProcessEnd {
    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true
        )]
        [int]
        $Item
    )
    Begin { "This is the Begin block." }
    Process {
        "Processing $Item"
    }
    End { "This is the End block." }
}

Let’s demonstrate the Process block in action. Temporarily define an array of integers using the syntax 1..5, meaning the array contains integers between 1 and 5 (inclusive). Pipe this array to the function and examine the output. Note the Begin and End blocks only display once, while the Process block outputs the number of items in the input array.

powershell function using pipeline input
Output of function with pipeline input

You can accomplish the same result by passing a variable to the function through the pipeline. Create a variable name $intArray and pass the variable to function through the pipeline.

powershell function using pipeline input from a variable
Example of using variable as pipeline input

The Process block can execute the incoming pipeline data because the $Item parameter is configured with the ValueFromPipeline property. The ValueFromPipeline argument tells the parameter to accept input from a pipeline object.

Adding Code to Begin and End Blocks

Let’s add functionality to the function by putting code in the Begin and End blocks. For the Begin block, create variables named $sum and $count with an initial value of 0.

In the Process block, add the current $Item value to $sum ($sum += $Item) and increment $count with 1 ($count++).

Finally, the End block displays the sum and number of items processed. Here is the updated function code.

function Show-BeginProcessEnd {
    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true
        )]
        [int]
        $Item
    )
    Begin {
        $sum = 0
        $count = 0
    }
    Process {
        "Processing $Item"
        $sum += $Item
        $count++
    }
    End {
        "The sum of the items is $sum."
        "The total number of items is $count."
    }
}

Here is the function in action, again passing integers 1..5 through the pipeline to the function. Remember that the Process block will execute for each item in the pipeline while the Begin and End blocks only run once. This process is how we only see the final output of the multiple Process blocks from the End blocks.

screenshot showing function output
Example of Process and End blocks in action

Processing Multiple Parameter Values

The current function can process multiple values from the pipeline. The function can also handle a single value using the $Item parameter, as shown in the screenshot below.

screenshot showing single parameter value
Function accepts single parameter value

However, what happens when you pass multiple values using the $Item parameter? Examine the output below using (1..5) as the parameter value.

screenshot showing error with multiple parameter values
Error when trying to process multiple parameter values

First, the $Item parameter is defined as a single integer, not an array of integers. Change the parameter definition to an integer array by adding [] in the data type field. Here is the updated parameter definition.

param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [int[]]
    $Item
)

With an updated parameter definition, the function still has an issue. If you rerun the command, the function displays the entire $Item array simultaneously, then displays an error. The error shows that the array does not support the += operation when adding $Item to $sum.

screenshot showing method invocation failure in powershell
Error showing invalid method for integer array

The Process block only natively iterates over pipeline values, not parameter values, so the function needs to be able to handle multiple values when passed through the parameter.

In the Process block, add a foreach loop to go through the $Item value using the variable $i as the value the loop currently processes. Modify the processing output and $sum addition statements to use $i instead of $item. Here is the updated Process block.

Process {
    foreach ($i in $Item) {
        "Processing $i"
        $sum += $i
        $count++
    }
}

With the updated function code complete, rerun the Show-BeginProcessEnd command using multiple pipeline or parameter values. The result is the same for either method now that the Process block can handle either.

screenshot showing powershell output for pipeline and parameter values
Showing output is same for both pipeline and parameter inputs

Now you might ask yourself, “How many times is the Process block executing in each example above?”. The Process block works with one value at a time for pipeline input. For the parameter input, the Process block only executes once. Each time the foreach statement iterates through whatever input is passed to it.

You can see this before if you add an output statement at the beginning of the Process block. Here’s another version of the Process block with Input: $Item added at the beginning. This statement shows what the Process block is currently working with.

Process {
    "Input: $Item"
    foreach ($i in $Item) {
        "Processing $i"
        $sum += $i
        $count++
    }
}

Here is the output when passing 1..5 to the function through the pipeline. Note how the output statement alternates between showing its current input (a single value from the pipeline) and what the foreach loop is currently processing. The foreach loop still executes even though $Item only contains single value.

screenshot showing powershell process block example
Process block executed multiple times for pipeline input

Here is the output when passing (1..5) as a parameter value. Note the input statement shows the Process block working with the entire array (1 2 3 4 5), then iterating through the foreach loop. In this case, the Process block only executes once while the foreach loop processes multiple items.

screenshot showing powershell process block example
Process block executed once for parameter values

The result is still the same, but the above output shows how the Process block natively iterates over pipeline values. However, if you want to process multiple values from a parameter, you must manually add the foreach loop in the Process block to iterate over the values.

Implementing PowerShell Begin Process End Blocks

For examples of implementing PowerShell Begin, Process, and End blocks, check out my SkypeTeamsOnlineManagement module on GitHub. While some of the code is outdated, several functions use input processing blocks, such as Add-SkypeOnlineUserLicense. The Begin block verifies connectivity to an Azure AD tenant, and then the Process block takes either pipeline or parameter input to assign licenses to one or more users.

Additional Reading:
Microsoft Learn: About Functions Advanced – Input processing methods

Summary

PowerShell Begin, Process, and End blocks add more methods for processing input for your function. Not all functions necessarily need these blocks. If you decide to add them to your function, you need a Process block at a minimum. Additional logic is necessary also to process multiple parameter inputs.

Enjoyed this article? Check out more of my PowerShell content here!