PowerShell and Named Parameters

PowerShell makes for easy named parameter creation (better than VB stuff, and much more better than DOS stuff). This was something that I asked in the last PowerShell training class I had, but the instructor didn’t quite get what I was asking (above his head, probably — laughs).

To utilize parameters (and named parameters), you can use “param” in your script. So, you can declare some parameter in the script such as:

param([string]$strClusterName = "MyDefaultClusterName")

This does a couple of things. 1) Creates a named parameter “strClusterName” of type “string”, and 2) sets a default value for it of “MyDefaultClusterName”. You could exclude the setting of a default, and just have a named parameter. Then you could test for a value, for null, or whatever you felt like. With that default value in there, if someone calls that script without passing a parameter, it uses the value you set as default (if that wasn’t clear).

So, when calling your script, you could pass a parameter like:

PS C:> myScriptsmegaScript.ps1 MyOtherClusterName

Or, to be explicit and avoid errors due to mismatched positional parameters, you could pass a named parameter to the script like so:

PS C:> myScriptsmegaScript.ps1 ?strClusterName MyOtherClusterName

Using the explicit parameter name when the script only accepts one parameter might seem a bit unnecessary at first glance, but a few months down the road when you’re looking at an example usage of your script and see that parameter name, you know what the hell that parameter is?

So, the name of the variable that you create in the param section of code is the name of the parameter to be used at run time. This holds true for functions, too. If you had a function like:

function dRdp() {
    param([string]$strServerName)
    mstsc.exe /v:$strServerName
}

then, like in the earlier example you could call it with a named parameter as such:

PS C:> dRdp -strServerName myServer010

Here, leaving off the parameter name yields the same results — the parameter is then considered a “positional” parameter. But, let’s say that you wanted to handle other optional parameters. Now the function is like:

function dRdp_v2() {
    param([string]$strServerName)
    mstsc.exe /v:$strServerName $args[0] $args[1]
}

When calling this function with no named parameters like so:

PS C:> dRdp_v2 myServer010 3389

the first parameter passed is used for the explicit param “$strServerName“, and the second parameter “3389” is returned by “$args[0]” as such:

$strServerName: myServer010
$args[0]: 3389

Not necessarily what you’d expect for the $args[] array. Notice here that the named parameter specified in the function definition gets set to the first positional parameter, and the rest of the positional parameters are placed into the $args[] array, starting at index 0.

Now, if you were to call the function with a named parameter, regardless of the position, the parameter in the function gets set to the passed named value, and the rest of the non-named parameters populate the $args[] array. So, calling the function in the following ways gives consistent results:

PS C:> dRdp_v2 -strServerName myServer010 3389
PS C:> dRdp_v2 3389 -strServerName myServer010

A few other notes:
There is another way to make parameters for a function: you can also define parameters within the parenthesis in the function definition. This is a bit more natural for people who are accustomed to programming languages in which this is how parameters are specified. For example, one can define the parameter in the function “dRdp_v2” as follows:

function dRdp_v2([string]$strServerName) {
    mstsc.exe /v:$strServerName $args[0] $args[1]
}

I am partial to this format, mainly because of past exposure, but also because of the increased typing efficiency/tightness of code.

Along the same lines of efficiency are named parameter abbreviations. When using named parameters in a function call or in calling a script, you can truncate the parameter name as much as desired, so long as the resultant name is still unique among the possible parameters. That is to say, the shortest non-ambiguous parameter name works. So, if you made a function with three parameters, “$serverName_str“, “$securePort_int” and “$nonSecurePort_int“, you could call the function as follows, and all would work:

PS C:> myFn -serverName_str svr010 -securePort_int 443 -nonSecurePort_int 665
PS C:> myFn -server svr010 -secure 443 -nonSec 665
PS C:> myFn -ser svr010 -sec 443 -n 665

And, the follow example does not work, as the first named parameter used, “-s“, is ambiguous:

## DOES NOT WORK -- the "-s" is ambiguous
PS C:> myFn -s svr010 -secure 443 -n 665
## DOES NOT WORK

There is at least some help available via PowerShell. The only place I’ve seen it, though, is:

PS C:> Get-Help -Full about_function

So, now named parameters are going to rule the world.

Advertisements

5 thoughts on “PowerShell and Named Parameters

  1. Thanks for the post. I was having a hard time finding how to make named parameters in PowerShell functions and your post shows this very succinctly — thanx again.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s