0

I'm not sure if this exists or is impossible, or would be best to just implement using two parameters, and I'm not sure if it would be more clear to ask using a generic context, or a more specific example, so I've provided both:

More Generic

I have a situation where I'd prefer a one of three different behaviors for a PowerShell function, based upon a parameter. It would act somewhat like a switch parameter, having one value ($false) if not provided, and a different value ($true) if provided. A third option will make a more specific behavior if a value (a [string]) is provided, which will then make it act more like a full parameter.

More Specific

Specifically, I'm thinking of a situation where objects that could be returned could have multiple ways of being unique, and multiple ways to filter and combine them. I would want to combine these three types of behavior in a filtering type parameter for a "Get-Stuff" Cmdlet, which I would want to call "Unique".

  • If not provided (e.g. Get-Stuff), there would be no "unique" type filtering provided for the output objects - all objects would be returned/piped to the output.
  • If the parameter were to be provided, but with no value (e.g. Get-Stuff -unique), I would want to have a default value for the parameter specify the name of a property, perhaps Name, where every returned result would be ensured to have a unique name, (perhaps the first one found, or indeterminate)
  • If the parameter was provided with a value (e.g. Get-Stuff -unique "Context","ID"), I would want it to use that value (or those values if it was for instance, an array of strings) to identify the field(s) that would need to be unique (in combination). Each returned/piped object would have a unique (combination of) value(s) for the named property(ies)

Regardless of the specific use of this information...

Actual functionality aside, is there a way to pass information to a Cmdlet in this way? I could combine a parameter and a switch (perhaps -unique with -indexFields), I suppose, or have a parameter override a switch, etc, but is it possible to use just a single argument instead of two?

Code Jockey
  • 6,611
  • 6
  • 33
  • 45

1 Answers1

1

You can fake it, if you want it, by looking at the value of the parameter and supplying default values, but I wouldn't advise it. While you can have mutually exclusive parameters by using parameter sets, this doesn't work with a parameter that has the same name, but different types in different parameter sets, so that option is out.

In your case I'd actually go with something like

Get-Stuff                     # without filtering
Get-Stuff -Unique             # Uniqueness by name only, by virtue of ...
Get-Stuff -Unique -Property Context,ID  # the Property parameter with a default value of Name

This mimics how things work in other cmdlets, like Select-Object, Measure-Object, Group-Object, etc.:

function Get-Stuff {
  param(
    [switch] $Unique,
    [array] $Property = @('Name')
  )
  # ...
}
Joey
  • 344,408
  • 85
  • 689
  • 683
  • Catch me if I'm wrong here, but the `-Property` parameter in `Select-Object` only returns those named properties. I would want to have different behavior (return entire objects), so I'd probably use different parameter names, which would make the mimicry less obvious -- I'm just saying that I'm not mimicking the function, so I wouldn't want to mimic the parameters so as to avoid confusion – Code Jockey Mar 08 '16 at 19:51
  • It's not unprecedented. The list of cmdlets with a `Property` parameter: `gcm -Type cmdlet | ? { $_.Parameters.Property }`. It contains `Sort-Object` as well, for example, or `Group-Object`, both of which do not remove properties from objects. It's just a common convention for specifying a list of properties that are special to the command. – Joey Mar 08 '16 at 19:54
  • also a parameter with default values will be optional, but if specified, won't it give an error? I'm not on a computer to test right at the moment... :-/ – Code Jockey Mar 08 '16 at 22:03