Prof. Powershell

More PowerShell CmdletBinding Fun

The cmldetBinding() attribute doesn't always need parameters, but it does need the Param keyword. Here's why it makes a difference.

Last time we looked at using the [cmdletBinding()] attribute to your PowerShell scripts or function, which treats your code like a cmdlet. Your code doesn't need to take any parameters, but you need to include the Param keyword:

Function Set-Foo {

[cmdletBinding(SupportsShouldProcess=$True)]
Param()
...

If you don't need to use one of the cmdletbinding features like SupportsShouldProcess, you don't have to use the [cmdletBinding()] attribute. You can still get cmdlet binding by using the [Parameter()] attribute on at least one parameter:

Function Set-Foo {

Param(
[Parameter()]
[string]$Path=$env:temp,
[Parameter()]
[switch]$Test
)
...

When I run Set-Foo, PowerShell will treat it like a cmdlet. But now for the fun part: Within the Parameter attribute you can specify a number of settings. Let's look at a few of the more common ones.

Position
If you want your parameter to be positional (that is, not have to explicitly include the parameter name), use this property:

Param(
[Parameter(Position=0)]
[string]$Path=$env:temp,
[Parameter()]
[switch]$Test
)

When I run my function, the first item after the command will be treated as the -Path parameter. I always start counting at 0. You can add parameters to your script in any order and the Position tag will sort everything out. A parameter without a Position must be explicitly typed. In this example, if I want to -Test, it must be included in the command. Also notice that I gave my positional parameter a default value/

Mandatory
There will often be situations where you will have a parameter that must have a value. You can include a tag to direct PowerShell to make the parameter mandatory:

Param(
[Parameter(Position=0,Mandatory=$True)]
[string]$Path=$env:temp,
[Parameter()]
[switch]$Test
)

To make the parameter non-mandatory, set the value to $False or simply delete. When the parameter is mandatory, if you don't specify it when you run the script or function, PowerShell will prompt you for it. But be aware of a little quirk here. When you mark a parameter as mandatory you must enter a value. If you have a default value, as I do in the example above, it is ignored. Mandatory expects you to type something, so default values are meaningless is this situation.

HelpMessage
If you use a mandatory parameter, I also recommend using the HelpMessage tag:

Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a file path to process")]
[string]$Path,
[Parameter()]
[switch]$Test
)

The message string is displayed when the user is prompted and ask for help:

PS C:\work> set-foo

cmdlet Set-Foo at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Path: !?
Enter a file path to process:
Path: c:\temp

I tend to keep these message short and to the point. Hopefully, your parameter name will help indicate what sort of value you are expecting.

There are many other parameter attributes we can set, but we'll save those for another day.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular