Hello!

There are many things I like about PowerShell, one of which is the automatic variables that are created. For example, $PsScriptRoot is set to the location of the running script (and if you run $PsScriptRoot in a .psm1 file, it sets $PSScriptRoot as the path of the file as opposed to the script.) And one of the automatic variables that I recently discovered is “PsBoundParams”. This handy little variable is a hash table that keeps track of what parameters have had arguements passed to them in either a script of a function.

Sounds useful, maybe, right?

In fact, I have found it incredibly useful and only wish I knew about it earlier. One of the clients I work for use Octopus Deploy in a big way - they have hundreds of step templates and dozens of script modules that are used by about 50 different dev teams, spawning out into hundreds of different projecs. But this shared resource can be a headache to manage. To give a bit of context, a step template in Octopus is literally a step in a process - see the demo site provided by Octopus for reference. These are written in C# or PowerShell and contain functions to perform a certain task. For example, in the Octopus Library online I submitted a step template to Execute a SQL Script.

A script module, on the other hand, is a set of PowerShell functions which, when added to a project, are available to be executed by step templates. So the idea is that you do much of the setup in a step template, such as set variables etc, and then execute functions within a step template.

But here’s the thing - a step template can be updated, but a project that makes use of that step template does not automatically update to the latest version, even if a new release is created after step template has been updated. A user has toforcibly update the version that a project is using.

Similarly, a script module can be updated, crucially - hang on, let me emphasize this… for any new release created, a script module IS ALWAYS the latest one.

So the problem here is that a function in a script module might be expecting a new and vital parameter that is not present in older versions step templates of the step template. And you can’t force hundreds of projects to be updated - well you can, but it’s a bit rude and your name will be mud ;-)

This is where PsBoundParams comes in useful - at the beginning of the function in the script module, if I check whether the PsBoundParams variable contains a key or not for the new parameter, I can determine which version of the step tempalte someone is on. If I’m lucky, I can set the value of the new parameter to a default.

Below is a little sample function that shows how PsBoundParams can be used.