1

I'm trying to write a failure simple script utilizing parameter sets to simplify input and validation. I'd like the script to look like this:

.\zipandrotate.ps1 -Zip [-AllButDays <int>] -Rotate [-MaxRetentionDays <int>]

-Zip and therefore -AllButDays are optional as is -Rotate and -MaxRetentionDays.

I have tried setting a default parameter set to zip but that did not work. I would like it to allow the execution to be: just zip, just rotate or both zip and rotate.

[CmdletBinding(DefaultParameterSetBame="zip")]
param(
    [Parameter(Mandatory=$false, ParameterSetName="zip")]
    [Switch]$Zip,

    [Parameter(Mandatory=$true, ParameterSetName="rotate")]
    [Switch]$Rotate,

    [Parameter(ParameterSetName="zip", Mandatory=$true)]
    [int]$AllButDays,

    [Parameter(ParameterSetName="rotate", Mandatory=$false)]
    [int]$MaxRetentionDays
)

I get the following error in PowerShell 5 (Windows 10) and PowerShell 4 (Windows 7):

PS C:\> .\zipandrotate.ps1 -Zip -AllButDays 2 -Rotate -MaxRetentionDays 2
C:\zipandrotate.ps1 : Parameter set cannot be resolved using the specified named
parameters.
At line:1 char:1
+ .\zipandrotate.ps1 -Zip -AllButDays 2 -Rotate -MaxRetentionDays 2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [zipandrotate.ps1], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,zipandrotate.ps1

Running the command three different ways tells me problem is in trying to use -Zip and -Rotate at the same time.

Works:

.\zipandrotate.ps1 -zip -allbutdays 2
.\zipandrotate.ps1 -rotate -maxretentiondays 90

Doesn't work:

.\zipandrotate.ps1 -zip -allbutdays 2 -rotate -maxretentiondays 90

So there are 4 paths I see my script going:

Allowed: Just zip, Just Rotate, Both
Not Allowed: None

Any advice on how I get there? Adding a third parameter set reversed the situation. Only -Zip and -Rotate worked; individual uses no longer had any unique cases to determine which parameter set they were. Is there a way to get the functionality I want to remove the need for an extra parameter to run -Zip or -Rotate alone?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Mr. Lost IT Guy
  • 137
  • 2
  • 12
  • If this is the only value required, can you just combine each set? `-ZipAllButDays:2`? – Eris Jan 29 '16 at 20:54

1 Answers1

1

I don't think what you're asking can be realized with static parameter sets. You're going to have to use either dynamic parameters or additional validation code inside the function.

However, I don't think I'd parameterize the script like you have in the first place. Your parameters consist of two switches, each of which is associated with a single parameter. Which means you could drop the switches entirely and just use the parameters. Since you seem to want to implement log rotation or something along the lines I would probably make both parameters optional and give them sane defaults, e.g. like this:

[CmdletBinding()]
param(
    [Parameter(Mandatory=$false)]
    [ValidateRange(1,120)]
    [int]$MaxRetention = 30,  # days

    [Parameter(Mandatory=$false)]
    [ValidateRange(1,30)]
    [int]$CompressAfter = 2   # days
)
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328