mandatory
would make both parameters required. I just need to make sure either path
or fileList
is always present.
I have been making do with the following but its not ideal:
function foo{
Param(
[string[]]$path
[string[]]$fileList
)
if (($null -eq $path) -and ($fileList -eq "")){Write-Error -Message "Paths or FilieList must be used" -ErrorAction Stop}
}
win11/pwsh 7.4
Try the following:
function foo {
[CmdletBinding(DefaultParameterSetName = 'PathAndFileList')]
Param(
[Parameter(ParameterSetName='PathOnly', Mandatory)]
[Parameter(ParameterSetName='PathAndFileList', Mandatory)]
[string[]]$Path,
[Parameter(ParameterSetName='FileListOnly', Mandatory)]
[Parameter(ParameterSetName='PathAndFileList', Mandatory)]
[string[]]$FileList
)
# Diagnostic output: Show which parameters were bound.
$PSBoundParameters
}
The key is to use parameter sets:
One parameter-specific set each, for when only only one of the two parameters is bound on invocation (PathOnly
, FileListOnly
).
A shared one (PathAndFileList
) for when both parameters are bound.
By marking both parameters as Mandatory
in all parameter sets they belong to, argument-less invocations trigger an interactive prompt for providing value(s) to the mandatory parameter(s), or - in CLI sessions launched via the -NonInteractive
parameter - trigger an error.
Via the DefaultParameterSetName
property in the [CmdletBinding()]
attribute you get to choose the
default parameter set, which in interactive execution, in turn determines which parameter(s) are prompted for in argument-less invocations (or, generally speaking, in invocations where not all mandatory parameters in the target parameter set are bound).
Caveat: If you choose PathAndFileList
as the default parameter set, both -Path
and -FileList
are prompted for in argument-less interactive calls, and must not be empty (by default, array-typed parameters do not accept an empty array), i.e. you must provide at least one value for both in order for the call to be made.
While there is a [AllowEmptyCollection()]
attribute, the problem is that if you add it to both parameters, you again enable an effectively argument-less invocation, if you enter nothing for / pass @()
to both parameters.
That said, the UX of the interactive prompts is generally poor and limited with respect to what parameter types it supports.
-NonInteractive
), which would make this problem moot.