Scripting Tips and Tricks: Param()

Param() - the next instalment in the exciting Scripting Tips and Tricks series!

I'm a tidy person: tidy desk, tidy mind, and all that jazz. I believe in being as thorough and proper in my scripts and functions as possible. To that end, I delight in using PowerShell features such as:

  • #Requires... to ensure certain conditions are met before we get into the meat of the script, e.g. that module X is present
  • Set-StrictMode... to ensure that certain coding rules are kept, e.g. check for uninitialized variables
  • CmdletBinding() ... to enable functionality analogous to that of a compiled cmdlet, e.g. common parameters such as -Vebrose

And...

  • Param()

 

With the Param() statement we enable a whole host of goodness for our function parameters. For example: we can define the position of parameter, we can make it mandatory, we can allow it to accept pipeline input and we can perform some pretty funky validation to make sure we have expected input.

Let's look at a Param() statement from a recent advanced function I wrote.

[CmdletBinding(SupportsShouldProcess)]

Param(

#The target domain

[parameter(Mandatory,Position=1)]

[ValidateScript({Get-ADDomain -Server $_})]

[String]$Domain,

 

#The number of days before which accounts are considered stale

[parameter(Mandatory,Position=2)]

[ValidateSet(60,90,120,150,180)]

[Int32]$StaleThreshold,

 

#Whether we are searching for user or computer accounts

[parameter(Mandatory,Position=3)]

[ValidateSet("User","Computer")]

[String]$AccountType,

 

#The OU we use as the basis of our search

[parameter(Position=4)]

[ValidateScript({Get-ADOrganizationalUnit -Identity $_})]

[String]$SourceOu,

 

#The OU to which we move the disabled accounts

[parameter(Position=5)]

[ValidateScript({Get-ADOrganizationalUnit -Identity $_})]

[String]$TargetOu,

 

#Whether to disable and move the accounts

[switch]

$Disable

)

Firstly, the comments above each parameter() declaration actually form help content (Get-Help) for the advanced function.

Also, note the use of Mandatory on certain parameters to make sure that key information is supplied to the function. If this information isn't supplied we'll get an error.

Then there's Position - this allows you to supply the parameter input in a predetermined sequence, without having to included the parameter name. I like to use position to provide some logic to the order of my parameters, e.g. specify a target domain before a target user. 

Now, let's look at some of the Validation statements. I use these to make sure the right information / object is supplied to the parameter. In the above example we have:

  • ValidateScript... takes the parameter input and executes some code against it to meet a predetermined condition. We expect the condition to return true, e.g. for the -Domain parameter run Get-ADDomain against the supplied string to make sure it equates to a valid domain
  • ValidateSet... makes sure the parameter input matches one of the values defined in the parameter set, e.g. -AccountType has to be 'User' or 'Computer'. The set is also exposed to Intellisense.

 

Here are some other useful validation statements:

  • [AllowNull()]
  • [AllowEmptyString()]
  • [AllowEmptyCollection()]
  • [ValidateNotNull()]
  • [ValidateNotNullOrEmpty()]
  • [ValidateCount(min,max)]
  • [ValidateLength(min,max)]
  • [ValidatePattern(pattern)]
  • [ValidateRange(min,max)]

 

And, finally, from the above example, notice that we have a [switch] statement in the Param() block.

Tidy functions, happy PoSh Chap!