I must write a script to get instances of Thing. Each Thing contains an event timestamp. I need to allow the user to specify a timestamp range.
- There are four (4) time-specifying parameters
- None are mandatory
- $Since and $StartTimestamp are mutually exclusive
- $Until and $EndTimestamp are mutually exclusive
- The script will translate $Since and $Until strings into an appropriate [datetime]
How can I use a ParameterSet to disable the use of both $Since and $StartTimestamp AND disable the use of both $Until and $EndTimestamp?
Posts about using multiple ParameterSets appear to grow exponentially with the number of parameters. Is this really the way?
There are posts about using a DynamicParam. I do not yet see where a DynamicParam would be appropriate for this. Is it?
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string] $ThingName
,[ValidateSet('Today', 'Yesterday', 'LastWeek')]
[string] $Since
,[datetime] $StartTimestamp
,[ValidateSet('Today', 'Now', 'Yesterday', 'LastWeek')]
[string] $Until
,[datetime] $EndTimestamp
)
Mutually exclusive parameters are indeed hard to implement using parameter sets, as of this writing (PowerShell v7.3.4):
A solution with the current features is possible, but cumbersome:
Note: I'm assuming that you want to allow only the following combinations (this complements the description of what you want to prevent in your question), and this positive formulation can expressed be via parameter sets:
-ThingNameonly, or combined with any of the following:-Sinceonly,-Untilonly-StartTimestamponly,-EndTimeStamponly-Sincecombined with-EndTimeStamp-Untilcombined with-StartTimeStampResulting syntax diagram (invoke the script with
-?):Taking a step back:
As zett42 points out, you can bypass the need for mutual exclusion if you provide only a single, polymorphous parameter for the start and end timestamp, respectively.
To that end, declare these parameters as
[object](so they can accept a value of any type), and:use a
[ValidateScript()]attribute to ensure that a value passed by the user can either be parsed as a[datetime]instance or is one of the predefined symbolic names, such asToday.In order to also support tab-completion, use an
[ArgumentCompleter()]attribute that completes the symbolic names.Note: The arrays of symbolic names are duplicated in the two attributes below: