What is $PSBoundParameters?

$PSBoundParameters in PowerShell is an automatic variable that is populated based on the parameters used with a function. It is a hashtable whose keys contain the parameter name used, and values contain the argument/value passed in. This can come in handy when you want to perform different tasks based on the parameters used in a function.

Automatic variables in PowerShell are variables that store a particular state. Although you can write to them, it is frowned upon to do so. For more information about automatic variables, check out this post: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.

Taking a look at $PSBoundParameters

Sometimes things make more sense if we can work with them tangibly.
Below is a function that will return the contents of $PSBoundParameters.

function Get-PSBoundParameters {
    [cmdletbinding()]
    param(
        [Parameter(

        )]
        [string]
        $ParamOne,

        [Parameter(

        )]
        [string]
        $ParamTwo
    )

    begin {
        
    }

    process {
        
    }

    end {

        return $PSBoundParameters

    }
}

Once we have this function in memory, we can call it, and get what is in $PSBoundParameters returned.

$params = Get-PSBoundParameters -ParamOne 'testOne' -ParamTwo 'testTwo'

In the above command, we are calling the function Get-PSBoundParameters, and passing testOne to ParamOne, and testTwo to ParamTwo.

Based on what we know now, the result should be a hashtable where the Keys contain ParamOne and ParamTwo, with the value of those keys being the arguments passed in.

Key Value
--- -----
ParamOne testOne
ParamTwo testTwo

params_visual.PNG

Working with the results as seen in the above image confirms this.

If you ever want to see what else an object can do, or the properties it has, pipe it to Get-Member.

You can see we have access to the various methods of $params, such as ContainsKey (which can be used to validate if a key (in this case parameter called) exists), and Add, which would let you add a key/value pair to the hashtable.

Working with $PSBoundParameters

Now that we’ve taken a peek under the hood, let’s work with $PSBoundParameters to take actions based on the parameters used when calling a function.

For this example, I have created a function that returns different results based on the parameters specified:

function Invoke-PSBoundParametersAction {
    [cmdletbinding()]
    param(
        [Parameter(

        )]
        [string]
        $ParamOne,

        [Parameter(

        )]
        [string]
        $ParamTwo,

        [Parameter(

        )]
        [string]
        $ParamThree
    )

    begin {

        #setup our return object
        $result = [PSCustomObject]@{

            SuccessOne = $false
            SuccessTwo = $false

        }        
    }

    process {

        #use a switch statement to take actions based on passed in parameters
        switch ($PSBoundParameters.Keys) {

            'ParamOne' {

                #perform actions if ParamOne is used
                $result.SuccessOne = $true
                
            }

            'ParamTwo' {

                #perform logic if ParamTwo is used
                $result.SuccessTwo = $true

            }

            Default {
                
                Write-Warning "Unhandled parameter -> [$($_)]"

            }
        }        
    }

    end {

        return $result

    }
}

Now let’s see it in action!

No parameters specified:

#test with no params
Invoke-PSBoundParametersAction 
noparam.PNG

As expected, the results indicate no change in the value of SuccessOne or SuccessTwo.

Now let’s try with just ParamOne:

#test with ParamOne
Invoke-PSBoundParametersAction -ParamOne 'value'
paramone.PNG

When we specify ParamOne, you can see it works as SuccessOne is now True.

Now let’s try with just ParamTwo:

#test with ParamTwo
Invoke-PSBoundParametersAction -ParamTwo 'value'
paramTwo.PNG

Looks good, now to give it a go with ParamOne and ParamTwo:

#test with ParamOne and ParamTwo
Invoke-PSBoundParametersAction -ParamOne 'value' -ParamTwo 'value'
bothParams.PNG

Looks like both of them had the appropriate action taken, as each success is set to True.

Now let’s see what happens if we use a parameter not specified in our switch statement:

#test with ParamThree
Invoke-PSBoundParametersAction -ParamThree 'value'

You can see our Write-Warning under the default switch clause worked.

Now let’s use all the parameters!

#test with ParamOne, ParamTwo, and ParamThree
Invoke-PSBoundParametersAction -ParamOne 'value' -ParamTwo 'value' -ParamThree 'value'
allthethings.PNG

Looks like the switch statement handled everything here.

Splatting the Parameters

Splatting in PowerShell is the act of taking a hashtable, and passing it as parameter/value pairs to a function. To do this, you call a function with a hashtable, but use the @ symbol instead of the $.

Here is a very simple example of splatting, with a slightly modified example set from above:

function Get-PSBoundParameters {
    [cmdletbinding()]
    param(
        [Parameter(

        )]
        [string]
        $ParamOne,

        [Parameter(

        )]
        [string]
        $ParamTwo
    )

    begin {

    }

    process {
        
    }

    end {

        Invoke-PSBoundParametersAction @PSBoundParameters

    }
}

function Invoke-PSBoundParametersAction {
    [cmdletbinding()]
    param(
        [Parameter(

        )]
        [string]
        $ParamOne,

        [Parameter(

        )]
        [string]
        $ParamTwo,

        [Parameter(

        )]
        [string]
        $ParamThree
    )

    begin {

        #setup our return object
        $result = [PSCustomObject]@{

            SuccessOne = $false
            SuccessTwo = $false

        }        
    }

    process {

        #use a switch statement to take actions based on passed in parameters
        switch ($PSBoundParameters.Keys) {

            'ParamOne' {

                #perform actions if ParamOne is used
                $result.SuccessOne = $true
                
            }

            'ParamTwo' {

                #perform logic if ParamTwo is used
                $result.SuccessTwo = $true

            }

            Default {
                
                Write-Warning "Unhandled parameter -> [$($_)]"

            }
        }        
    }

    end {

        return $result

    }
}

The second function is the same, but the first function has been modified to call the second function with $PSBoundParameters splatted.

Invoke-PSBoundParametersAction @PSBoundParameters

With these two functions in memory, let’s take a look at the result of calling the first function as such:

#test splatting
Get-PSBoundParameters -ParamOne 'value'
splat.PNG

Since the parameter names matched, it passed the parameter/values along to the second function.

Wrapping things up

As we’ve seen in this post, $PSBoundParameters can be handy depending on your use-case. Whether you are validating a parameter exists, or passing things along via splatting, it helps keep things more concise and clean versus the alternatives. If you have any questions or feedback, please leave a comment below!