Skip to the main content.

ScriptRunner Blog

A Beginner's Guide to Parameter Binding

Table of Contents

Post Featured Image

Parameter binding is a fundamental concept in PowerShell. You might be puzzled if you don't fully grasp this concept, as I recently found out.

I re-read advanced functions and tried a simple calculator script to test my recall. The problem started when I tried to supply parameter values from the pipeline. This post covers two key PowerShell pipeline parameter binding concepts: "byValue" and "byProperty".

Let us examine my first attempt at my calculator program. Below is a simple PowerShell script to perform basic arithmetic operations on two numbers.

 

Screenshot: Calculator script. Name of Function: Get-Calculation; Three Parameters: firstNumber, secondNumber and Operator

Figure 1a: Simple Calculator Part 1. Name of Function: Get-Calculation; Three Parameters: $firstNumber, $secondNumber and $operator. Parameter Attributes: Mandatory and Accept value from Pipeline. The operator parameter has a fixed set of values.


Screenshot: Calculator script. Defining the output object and writing the output into the pipeline

Figure 1b: Simple Calculator Part 2. Defining the output object and writing the output object into the pipeline.

 

The problem arises when I create a custom object with properties matching my function parameters and pass it to the Get-Calculation function in the pipeline, resulting in an error (Figure 3).

Screenshot: Passing a custom PS Object to Get-Calculation

Figure 3: Passing a custom PS Object to Get-Calculation


        

Troubleshooting with Trace-Command

To better understand and debug the issue, I used the Trace-Command cmdlet to observe parameter binding in the pipeline. I ran trace-command with following options to observe parameter binding “ParameterBinderBase, ParameterBinderController, ParameterBinding”. The screenshot below shows the output from Trace-Command (Figure 4).
Screenshot: Using Trace-Command to examine parameter binding

Figure 4: Using Trace-Command to examine parameter binding

 

In figure 5, the entire object ($myObj) is supplied as the parameter value instead of its properties.

Screenshot: Parameter binding

Figure 5: Parameter binding


        

Parameter Binding: byValue vs. byProperty

I set “ValueFromPipeline=$True”, causing the Pipeline to bind “byValue”.

"Bind by Value" means the incoming object is used as the parameter value without processing its properties. The pipeline attempts to bind the entire object (e.g., {firstNumber=1; secondNumber=4; operator=+}) to parameters like "firstNumber."

The solution is to bind “byProperty”. We must explicitly instruct the pipeline to bind the object's properties to our parameter. As shown below we changed our original script to bind byProperty (Figure 6).

Screenshot: Parameter attribute to accept value by propert

Figure 6: Parameter attribute to accept value by property

 

Next, we again observe the behavior using Trace-Command. This time, we can observe that the object properties are accurately bound to our parameters (Figure 7). For this to work, the object's properties must match the function parameter names.

Screenshot: Trace-Command reveals, parameter binding is successful

Figure 7: Parameter binding is successful


        

Test: Parameter Binding byValue and byProperty

In the next program iteration, we modified parameters to accept both by value and by property. The operator parameter was made non-mandatory with a default value of "+".
Screenshot: Accepting parameter byValue and byProperty

Figure 8: Accepting parameter byValue and byProperty


 

Now our function accepts parameter values using both the byValue and byProperty option. Here's a simple example: we send an Int object (Figure 9) and a custom PS object (Figure 10).

Screenshot: Supplying two objects to Get-Valculation

Figure 9: Supplying two objects to Get-Calculation


 

The first result of 8 might be confusing, but the program worked as expected for the second object (I'll leave the operator property as homework for you).

We are going to observe binding using our good old friend the Trace-command. In Figure 10, the Int object 4 binds to both firstNumber and secondNumber, resulting in a sum of 8. This shows that with the "byValue" option, the pipeline uses the same object for all parameters accepting pipeline values.

Screenshot: Parameter binding for Int object

Figure 10: Parameter binding for Int object


 

For our PS custom object, the pipeline initially attempts byValue binding, fails, and then switches to byProperty, binding by property name (Figure 11).

Screenshot: Parameter binding for PS custom object

Figure 11: Parameter binding for PS custom object


        

Conclusion

Here are some key takeaways from this post:

  1. Default option for parameter binding is to bind by value.
  2. If we have selected both byValue and byProperty option, the pipeline will start by binding using byValue option.
  3. When parameters are provided directly to the function, the process block runs only once.
  4. When parameters are piped, the process block runs for each object.

I hope this post would help you to further understand and implement advanced functions correctly.

 

 

Related posts

13 min read

Mastering Changelog Management with PowerShell

Changelogs keep your software updates clear and organized. Learn the best practices for creating and managing them in...

14 min read

How to Use Winget and PowerShell for Efficient App Deployment

Boost IT efficiency with Winget and PowerShell! Learn how to automate app installations, updates, and management...

17 min read

How to Leverage .NET in PowerShell for event-driven scripting

Extend PowerShell with .NET for powerful event automation. Learn how to monitor and handle system events like a pro!...

About the author: