使用参数来约束多个互斥的依赖项

时间:2016-10-10 01:49:53

标签: powershell design-patterns parameter-sets

当脚本的签名通过参数区分(单数)时,参数集对我有意义。

示例:

.\myscript.ps1 -InputFile [-Optional1] [-Optional2]...
.\myscript.ps1 -ArrayOfNames [-Optional1] [-Optional2]...

我的问题是:如果您希望支持并行(或多个)依赖关系,参数设置是否是逻辑选择,如下所述?

这是我目前的情况。 我正在添加对查询包含时间戳的日志的现有脚本的支持。该脚本应接受csv文件一组smtp地址,以确定要查询的用户。

脚本支持开始和结束日期参数整数值,以便于报告过去的n天,从当前日期开始计算。

我希望支持的结果是:

.\myScript -InputFile -StartDate -EndDate [-Optional1] [-Optional2]...
.\myScript -InputFile -LastNumDays [-Optional1] [-Optional2]...
.\myScript -Smtp -StartDate -EndDate [-Optional1] [-Optional2]...
.\myScript -Smtp -LastNumDays [-Optional1] [-Optional2]...

如果我不尝试合并我的两个要求,则以下两个参数定义中的任何一个都可以正常工作:

[Parameter(Mandatory=$true, ParameterSetName="Input")]
[ValidateScript({Test-Path -Path $_ -PathType Leaf})][string] $InputFile,

[Parameter(Mandatory=$true, ParameterSetName="NoInput")]
[ValidateNotNullOrEmpty()][String[]] $Smtp

Get-Help将预期用量显示为:

.\myScript.ps1 -InputFile <String> [<CommonParameters>]
.\myScript.ps1 -Smtp <String[]> [<CommonParameters>]

如果我改为配置以下内容:

[Parameter(Mandatory=$true, ParameterSetName="NotRange")]
[ValidateNotNullOrEmpty()][int] $LastNumDays = 30, # init 30 days default

[Parameter(Mandatory=$true, ParameterSetName="Range")]
[ValidateNotNullOrEmpty()][Alias("Start")] [DateTime] $StartDate,

[Parameter(Mandatory=$true, ParameterSetName="Range")]
[ValidateNotNullOrEmpty()][Alias("End")] [DateTime] $EndDate

Get-Help将预期用量显示为:

.\myScript.ps1 -LastNumDays <Int32> [<CommonParameters>]
.\myScript.ps1 -StartDate <DateTime> -EndDate <DateTime> [<CommonParameters>]

问题在于我似乎无法将这两个依赖项合并到本文开头所述。我使用参数集合并这两个逻辑依赖关系的尝试失败的一个例子如下:

[Parameter(Mandatory=$true, ParameterSetName="Input")]
[ValidateScript({Test-Path -Path $_ -PathType Leaf})][string] $InputFile,

[Parameter(Mandatory=$true, ParameterSetName="NoInput")]
[ValidateNotNullOrEmpty()][String[]] $Smtp,

[Parameter(Mandatory=$true, ParameterSetName="NotRange")]
[Parameter(Mandatory=$true, ParameterSetName="Input")]
[Parameter(Mandatory=$true, ParameterSetName="NoInput")]
[ValidateNotNullOrEmpty()][int] $LastNumDays = 30, # init 30 days default

[Parameter(Mandatory=$true, ParameterSetName="Range")]
[Parameter(Mandatory=$true, ParameterSetName="Input")]
[Parameter(Mandatory=$true, ParameterSetName="NoInput")]
[ValidateNotNullOrEmpty()][Alias("Start")] [DateTime] $StartDate,

[Parameter(Mandatory=$true, ParameterSetName="Range")]
[Parameter(Mandatory=$true, ParameterSetName="Input")]
[Parameter(Mandatory=$true, ParameterSetName="NoInput")]
[ValidateNotNullOrEmpty()][Alias("End")] [DateTime] $EndDate

Get-Help结果不正确b / c前两个用法语句允许同时使用LastNumDays和Start / EndDate参数:

.\myScript.ps1 -InputFile <String> -LastNumDays <Int32> -StartDate <DateTime> -EndDate <DateTime> [<CommonParameters>]

.\myScript.ps1 -Smtp <String[]> -LastNumDays <Int32> -StartDate <DateTime> -EndDate <DateTime> [<CommonParameters>]

.\myScript.ps1 -LastNumDays <Int32> [<CommonParameters>]
.\myScript.ps1 -StartDate <DateTime> -EndDate <DateTime> [<CommonParameters>]

我已经测试了强制性true / false的不同组合,并且包含/省略了我的命名参数集但没有成功。

我现在怀疑我的要求可能不适合用例参数集旨在支持但我不知道我应该使用什么模式和练习。

如果不使用参数集,如何正确定义这两个依赖项的使用语法?我觉得我必须避免在我的代码中使用测试来宣布Get-Help中未定义的依赖项。

谢谢!

1 个答案:

答案 0 :(得分:0)

您需要使每个参数集都是唯一的,因此PowerShell可以区分彼此。为简单起见,我将参数集命名为A到D:

答:-InputFile -StartDate -EndDate
B:-InputFile -LastNumDays
C:-Smtp -StartDate -EndDate
D:-Smtp -LastNumDays

现在将每个参数与它出现的每个参数集相关联:

Param(
  [Parameter(Mandatory=$true, ParameterSetName="A")]
  [Parameter(Mandatory=$true, ParameterSetName="B")]
  [string]$InputFile,

  [Parameter(Mandatory=$true, ParameterSetName="C")]
  [Parameter(Mandatory=$true, ParameterSetName="D")]
  [String[]]$Smtp,

  [Parameter(Mandatory=$true, ParameterSetName="B")]
  [Parameter(Mandatory=$true, ParameterSetName="D")]
  [int]$LastNumDays,

  [Parameter(Mandatory=$true, ParameterSetName="A")]
  [Parameter(Mandatory=$true, ParameterSetName="C")]
  [DateTime]$StartDate,

  [Parameter(Mandatory=$true, ParameterSetName="A")]
  [Parameter(Mandatory=$true, ParameterSetName="C")]
  [DateTime]$EndDate
)

输出:

PS C:\> .\test.ps1 -?
test.ps1 -InputFile <string> -LastNumDays <int> [<CommonParameters>]
test.ps1 -InputFile <string> -StartDate <datetime> -EndDate <datetime> [<CommonParameters>]
test.ps1 -Smtp <string[]> -LastNumDays <int> [<CommonParameters>]
test.ps1 -Smtp <string[]> -StartDate <datetime> -EndDate <datetime> [<CommonParameters>]

请注意,为必需参数(-LastNumDays)提供默认值毫无意义,因为无论如何都需要提供值。