Search code examples
powershell

Why do I need to use 'parametersetname' with a PowerShell switch?


My question is about the parameter field 'parametersetname' and its mysterious need to be included.

I have this PowerShell (v3) script called test.ps1:

param([parameter(parametersetname="anything")][switch]$foo=$false)
$foo.IsPresent

If I run it in the PowerShell IDE cmd line like this:

.\test.ps1

I get

> False

whereas calling it with

.\test.ps1 -foo

I get

> True

Both good. However it has taken me a while (ages) to realise that for switch to work, I must add this descriptor "parametersetname".

Because if I repeat my test, but omit "parametersetname" like this:

param([parameter][switch]$foo=$false)
$foo.IsPresent

When I run this:

.\test.ps1

I get error:

Cannot process argument transformation on parameter 'foo'. Cannot convert the "False" value of type "System.Management.Automation.SwitchParameter" to type "System.Management.Automation.ParameterAttribute".

whereas calling it with

.\test.ps1 -foo

I get

Missing an argument for parameter 'foo'. Specify a parameter of type 'System.Management.Automation.ParameterAttribute' and try again.

Does anyone know why?

What magic is 'parametersetname' doing?


Solution

  • You don't need to use parametersetname, but you do need the brackets after Parameter.

    If you omit the brackets it seems that powershell is reading it as type information for the parameter and trying to cast the parameter to that type, instead of treating it as a parameter attribute.

    param([Parameter()][switch]$foo=$false)
    

    Works as does

    param([switch]$foo=$false)