bar*_*per 7 powershell validateset
我正在寻找一种方法来制作接收参数的 cmdlet,并且在键入时,它会根据预定义的选项数组提示完成建议。
我正在尝试这样的事情:
$vf = @('Veg', 'Fruit')
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateSet($vf)]
$Arg
)
}
Run Code Online (Sandbox Code Playgroud)
预期结果应该是:
在编写“Test-ArgumentCompleter F”时,单击 tub 按钮后,F 自动完成为 Fruit。
PowerShell 通常要求属性属性是文字(例如,'Veg'
)或常量(例如,$true
)。
但是,该[ValidateSet()]
属性仅接受字符串(按需化)文字数组或 - 在PowerShell (Core) v6 及更高版本中-类型文字(见下文)。
更新:
如果您使用的是PowerShell (Core) v6+,则有一个基于定义实现接口的自定义的更简单的解决方案- 请参阅iRon 有用答案中的第二个解决方案。class
System.Management.Automation.IValidateSetValuesGenerator
即使在Windows PowerShell 中,如果您的验证值可以定义为enum
类型,那么更简单的解决方案也是可能的- 请参阅Mathias R. Jessen 的有用答案。
要基于非文字值数组获得所需的功能,您需要组合其他两个属性:
[ArgumentCompleter()]
用于动态制表符完成。
[ValidateScript()]
使用脚本块确保在命令提交时参数确实是数组中的值。
# The array to use for tab-completion and validation.
[string[]] $vf = 'Veg', 'Fruit'
function Test-ArgumentCompleter {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
# Tab-complete based on array $vf
[ArgumentCompleter(
{ param($cmd, $param, $wordToComplete) $vf -like "$wordToComplete*" }
)]
# Validate based on array $vf.
# NOTE: If validation fails, the (default) error message is unhelpful.
# Unfortunately, this cannot be helped in *Windows PowerShell*, but in
# PowerShell (Core) 7+, you can add an `ErrorMessage` property:
# [ValidateScript({ $_ -in $vf }, ErrorMessage = 'Unknown value: {0}')]
[ValidateScript( { $_ -in $vf })]
$Arg
)
"Arg passed: $Arg"
}
Run Code Online (Sandbox Code Playgroud)
为了补充@mklement0和@Mathias的答案,使用动态参数:
$vf = 'Veg', 'Fruit'
function Test-ArgumentCompleter {
[CmdletBinding()]
param ()
DynamicParam {
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$AttributeCollection.Add($ParameterAttribute)
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($vf)
$AttributeCollection.Add($ValidateSetAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('Arg', [string], $AttributeCollection)
$RuntimeParameterDictionary.Add('Arg', $RuntimeParameter)
return $RuntimeParameterDictionary
}
}
Run Code Online (Sandbox Code Playgroud)
根据您希望如何预定义参数值,您还可以使用动态 validateSet 值:
Class vfValues : System.Management.Automation.IValidateSetValuesGenerator {
[String[]] GetValidValues() { return 'Veg', 'Fruit' }
}
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateSet([vfValues])]$Arg
)
}
Run Code Online (Sandbox Code Playgroud)
注:该
IValidateSetValuesGenerator
班[read: interface]
是在PowerShell的6.0中引入
除了mklement0的出色答卷,我觉得有义务指出,在5及以上版本,你有一个稍微简单的替代方法可供选择:enum
的
一个enum
,或一个“枚举类型”,是标签的静态列表与下面积分值(数字)相关联的(字符串) -和通过约束一个参数来枚举类型,PowerShell中会自动验证针对它的输入值并提供参数完成:
enum MyParameterType
{
Veg
Fruit
}
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[MyParameterType]$Arg
)
}
Run Code Online (Sandbox Code Playgroud)
尝试使用 tab 完成参数-Arg
现在将循环抛出匹配的有效枚举标签MyParameterType
:
enum MyParameterType
{
Veg
Fruit
}
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[MyParameterType]$Arg
)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
427 次 |
最近记录: |