lit*_*lit 2 parameters powershell parameter-sets powershell-7.3
我必须编写一个脚本来获取 Thing 的实例。每个事物都包含一个事件时间戳。我需要允许用户指定时间戳范围。
如何使用 ParameterSet 禁用 $Since 和 $StartTimestamp 的使用并禁用 $Until 和 $EndTimestamp 的使用?
关于使用多个参数集的帖子似乎随着参数数量呈指数增长。真的是这样吗?
有关于使用 DynamicParam 的帖子。我还没有看到 DynamicParam 适合于此。是吗?
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string] $ThingName
,[ValidateSet('Today', 'Yesterday', 'LastWeek')]
[string] $Since
,[datetime] $StartTimestamp
,[ValidateSet('Today', 'Now', 'Yesterday', 'LastWeek')]
[string] $Until
,[datetime] $EndTimestamp
)
Run Code Online (Sandbox Code Playgroud)
截至撰写本文时,互斥参数确实很难使用参数集来实现(PowerShell v7.3.4):
具有当前功能的解决方案是可能的,但很麻烦:
注意:我假设您只想允许以下组合(这补充了您想要在问题中防止的内容的描述),并且这种积极的表述可以通过参数集来表达:
-ThingName仅,或与以下任何一项组合:-Since仅仅、-Until仅仅-StartTimestamp仅仅、-EndTimeStamp仅仅-Since结合-EndTimeStamp-Until结合-StartTimeStamp[CmdletBinding(DefaultParameterSetName='ThingAlone')]
param (
[Parameter(Mandatory, Position=0)]
[string] $ThingName
,
[Parameter(Mandatory, ParameterSetName='SinceAlone')]
[Parameter(Mandatory, ParameterSetName='StartSinceEndUntil')]
[Parameter(Mandatory, ParameterSetName='StartSinceEndTimestamp')]
[ValidateSet('Today', 'Yesterday', 'LastWeek')]
[string] $Since
,
[Parameter(Mandatory, ParameterSetName='StartTimestampAlone')]
[Parameter(Mandatory, ParameterSetName='StartTimestampEndUntil')]
[Parameter(Mandatory, ParameterSetName='StartTimestampEndTimestamp')]
[datetime] $StartTimestamp
,
[Parameter(Mandatory, ParameterSetName='UntilAlone')]
[Parameter(Mandatory, ParameterSetName='StartSinceEndUntil')]
[Parameter(Mandatory, ParameterSetName='StartTimestampEndUntil')]
[ValidateSet('Today', 'Now', 'Yesterday', 'LastWeek')]
[string] $Until
,
[Parameter(Mandatory, ParameterSetName='EndTimeStampAlone')]
[Parameter(Mandatory, ParameterSetName='StartSinceEndTimestamp')]
[Parameter(Mandatory, ParameterSetName='StartTimestampEndTimestamp')]
[datetime] $EndTimestamp
)
$PSCmdlet.ParameterSetName
Run Code Online (Sandbox Code Playgroud)
生成的语法图(使用 调用脚本-?):
YourScript.ps1 [-ThingName] <string> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -Since <string> -EndTimestamp <datetime> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -Since <string> -Until <string> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -Since <string> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -StartTimestamp <datetime> -EndTimestamp <datetime> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -StartTimestamp <datetime> -Until <string> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -StartTimestamp <datetime> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -Until <string> [<CommonParameters>]
YourScript.ps1 [-ThingName] <string> -EndTimestamp <datetime> [<CommonParameters>]
Run Code Online (Sandbox Code Playgroud)
退一步说:
正如zett42指出的,如果您分别为开始和结束时间戳提供单个多态参数,则可以绕过互斥的需要。
为此,将这些参数声明为[object](以便它们可以接受任何类型的值),并且:
使用[ValidateScript()]属性来确保用户传递的值可以被解析为实例[datetime],或者是预定义的符号名称之一,例如Today.
为了还支持制表符完成,请使用[ArgumentCompleter()]完成符号名称的属性。
注意:符号名称数组在以下两个属性中重复:
[CmdletBinding()]
param (
[Parameter(Mandatory, Position=0)]
[string] $ThingName
,
[ArgumentCompleter({
param($cmd, $param, $wordToComplete)
'Today', 'Yesterday', 'LastWeek' -like "$wordToComplete*"
})]
[ValidateScript({
if ($_ -notin 'Today', 'Yesterday', 'LastWeek' -and $null -eq ($_ -as [datetime])) {
throw "Invalid -Since argument."
}
$true
})]
[object] $Since
,
[ArgumentCompleter({
param($cmd, $param, $wordToComplete)
'Today', 'Now', 'Yesterday', 'LastWeek' -like "$wordToComplete*"
})]
[ValidateScript({
if ($_ -notin 'Today', 'Now', 'Yesterday', 'LastWeek' -and $null -eq ($_ -as [datetime])) {
throw "Invalid -Until argument."
}
$true
})]
[object] $Until
)
# Translate the -Since and -Until arguments into [datetime] instances.
$i = 0
$sinceTimestamp, $untilTimestamp =
$Since, $Until | ForEach-Object {
switch ($_) {
$null { if ($i -eq 0) { Get-Date -Date 0 } else { Get-Date }; break }
Now { Get-Date; break }
Today { (Get-Date).Date; break }
Yesterday { (Get-Date).Date.AddDays(-1); break }
LastWeek { (Get-Date).Date.AddDays(-7); break }
Default { $_ -as [datetime] }
}
++$i
}
if ($untilTimestamp -lt $sinceTimestamp) { Throw "The -Since argument must predate the -Until argument." }
# Diagnostic output.
[pscustomobject] @{
Since = $sinceTimestamp
Until = $untilTimestamp
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
129 次 |
| 最近记录: |