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.

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.

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.

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.

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.

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

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
.

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.

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.

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.

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!