3
votes

In Powershell V2, I am trying to use the Param() declaration to parse the switches passed into a script. My problem can be illustrated using this script (example.ps1):

Param(
    [switch] $A,
    [switch] $B,
    [switch] $C
)
echo "$A, $B, $C"

My problem is that this script will silently ignore any incorrect switches. For instance, "example.ps1 -asdf" will just print "False, False, False", instead of reporting the incorrect usage to the user.

I noticed that the behavior changes if I add a positional parameter:

Param(
    [switch] $A,
    [switch] $B,
    [switch] $C,
    [parameter(position=0)] $PositionalParameter
)
echo "A:$A, B:$B, C:$C"

Now, a ParameterBindingException will be raised if I run "example2.ps1 -asdf". But, "example2.ps1 asdf" (notice the parameter without a leading dash) will still be silently accepted.

I have two questions:

  1. Is there a way to get Powershell to always report an extra argument to my script as an error? In my script, I just want to allow the fixed set of switches (-A, -B, -C), and any other parameter should be an error.

  2. When a parameter error is detected, can I get Powershell to print the usage (i.e., "get-help example.ps1") instead of raising a ParameterBindingException?

2
Do you must have Param ( [switch] $x ) or will switch ($a) { A B C default } will work? - AvkashChauhan
I don't think that would work because I need to support all combinations of switches. It is a script that has multiple phases, and I want to be able to disable individual phases: run.ps1 -SkipPhase1 -SkipPhase5 - Igor ostrovsky
@AvkashChauhan: I may have also misunderstood your point. If you are suggesting that I loop through the arguments myself, I can definitely do that. I've been trying to figure out whether the Param() declaration is more convenient, but maybe looping through the parameters is the thing to do. - Igor ostrovsky
here are several scenarios discussed: technet.microsoft.com/en-us/library/ff730937.aspx - AvkashChauhan
@AvkashChauhan: Thanks, but that is a completely different usage of the "switch" keyword. My question is about the usage of [switch], as discussed here: technet.microsoft.com/en-us/library/hh847743 - Igor ostrovsky

2 Answers

5
votes

You can just try using CmdletBinding as explain in about_Functions_CmdletBindingAttribute, in functions that have the CmdletBinding attribute, unknown parameters and positional arguments that have no matching positional parameters cause parameter binding to fail.

[CmdletBinding()]
Param(
      [switch] $A,
      [switch] $B,
      [switch] $C)

echo "A:$A, B:$B, C:$C"
2
votes

You can try in this way checking $args

Function myfunction
{
  param(
        [switch] $A,
        [switch] $B,
        [switch] $C
)

foreach ( $key in $PSBoundParameters.keys )
{    
  if ( $args -gt 0) 
        {$script:test = $false ; break}
    else
        {$script:test = $true}
}    

if ($test)     
{ 
 "Parameters are ok" # ... your code script here
}    
else
{
  "Parameters error. Check Command" # or get-help myfuction
}
}