Friday, August 26, 2016

PowerShell v2 ParameterSets for Dummies

I am a big fan of PowerShell functions. Particularly the ones that are more complex, and, with a few exceptions, could easily pass as full-blown cmdlets. In spite of this, I still havent gotten my head around one of the features, ParameterSets, which I think are very powerful. I threw out a Tweet to see if anyone could throw me a line, and, a few folks gave me links. (Thanks Ed, Trevor and Jon). After reading through Eds link:
Use Parameter Sets to Simplify PowerShell Commands
I decided Id start from scratch with some basics and build up from there. So, I started with this:
function Test-ParameterSet
{
      param(
            $one,
            [Parameter(
                  ParameterSetName = Two
            )]
            [Switch]
            $Two,
            [Parameter(
                  ParameterSetName = Three
            )]
            [Switch]
            $Three
      )
     
      $one
}
When I run this, I approach it several different way to see what breaks, and, what works:
Test-ParameterSet -One 1
produces:
Test-ParameterSet : Parameter set cannot be resolved using the specified named parameters.

At C:UserswsteeleAppDataLocalTemp562a6843-2adf-4bba-ad3e-f22052430aca.ps1:20 char:18
+ Test-ParameterSet <<<<  -One 1 -Two -three
    + CategoryInfo          : InvalidArgument: (:) [Test-ParameterSet], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Test-ParameterSet
These two work:
Test-ParameterSet -One 1 –Two
Test-ParameterSet -One 1 –Three
But, this doesnt:
Test-ParameterSet –One1 –Two –Three
And, neither does this:
Test-ParameterSet –Two –Three
So, these are some simple, basic tests. Taking it up one step I add a parameter, $Four, that depends on $three by being a member of the Three parameter set.
function Test-ParameterSet
{
      param(
            $one,
            [Parameter(
                  ParameterSetName = Two
            )]
            [String]
            $Two,
            [Parameter(
                  ParameterSetName = Three
            )]
            [String]
            $Three,
            [Parameter(
                  ParameterSetName = Three
            )]
            [String]
            $Four
      )
     
      if($one) {
            $one
      }
      if($two) {
            $two
      }
      if($three) {
            $three
      }
      if($Four) {
            $four
      }
}
The same rules as above apply:

  • any parameter not a member of a specific parameter set can be used so long as one member of the parameter set parameters is called
  • unless a parameter in a parameterset is configured with Mandatory = $true you can call other parameterset members without calling the given parameter
Point 1any parameter not a member of a specific parameter set can be used so long as one member of the parameter set parameters is called
Test-ParameterSet -one 1 -Four 4
returns 1 and 4. Note that -Three is neither used nor required.

Point 2unless a parameter in a parameterset is configured with Mandatory = $true you can call other parameterset members without calling the given parameter
By adding Mandatory = $true to the [Parameter()] definition for three, the above command prompts you for -Three, but, once executed, runs fine.
For me the, big lesson here is that, if you  add parameter sets, remember, you must call at least one member of one parameter set or else the function/script will not run. I need to explore how this works with dynamic parameters, but, for now, I can at least start using parameter sets more effectively in my scripts with an idea of how they basically work.

As you explore how to work with this, I found the Get-Help cmdlet really useful as it paints a picture of what your parameter sets really are in usage, not just as a construct in your head. Using my last incarnation of the above function,
function Test-ParameterSet
{
      param(
            $one,
            [Parameter(
                  ParameterSetName = Two
            )]
            [String]
            $Two,
            [Parameter(
                  Mandatory = $true,
                  ParameterSetName = Three
            )]
            [String]
            $Three,
            [Parameter(
                  ParameterSetName = Three
            )]
            [String]
            $Four
      )
     
      if($one) {
            $one
      }
      if($two) {
            $two
      }
      if($three) {
            $three
      }
      if($Four) {
            $four
      }
}
I get the following when I run Get-Help:
Test-ParameterSet [-one ] [-Two ] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]
Test-ParameterSet [-one ] -Three [-Four ] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]
Notice that the -Three parameter in the second collection does not have brackets around it. This indicates that parameter is Mandatory. Compare against the Two parameter set parameter collection in which both parameters (-One and -Two) are bracketed, i.e., not mandatory. I highlighted the function specific parameters (i.e., non-common parameters) to emphasize the breakdown of the parameter sets. Also emphasized is the -Three parameter in the Three parameter set to demonstrate the difference between Mandatory = $true and Mandatory = $false (the default).
<

Related Post:

0 comments:

Post a Comment

 
Copyright 2009 Information Blog
Powered By Blogger