如何从数组中获取 Powershell 验证脚本参数?
How to have a Powershell validatescript parameter pulling from an array?
我有一个具有很多高级功能的模块。
我需要使用一长串 ValidateSet 参数。
我想将可能参数的整个列表放在一个数组中,然后在函数本身中使用该数组。
如何从数组中提取整个集合的列表?
New-Variable -Name vars3 -Option Constant -Value @("Banana","Apple","PineApple")
function TEST123 {
param ([ValidateScript({$vars3})]
$Fruit)
Write-Host "$Fruit"
}
问题是,当我使用该函数时,它不会从常量中提取内容。
TEST123 -Fruit
如果我指定常量的索引值,它就可以工作。
TEST123 -Fruit $vars3[1]
它returns苹果。
你误解了 ValidateScript ...
ValidateScript Validation Attribute
The ValidateScript attribute specifies a script that is used to
validate a parameter or variable value. PowerShell pipes the value to
the script, and generates an error if the script returns $false or if
the script throws an exception.
When you use the ValidateScript attribute, the value that is being
validated is mapped to the $_ variable. You can use the $_ variable to refer to the value in the script.
...有效。正如其他人到目前为止所指出的那样。您没有使用脚本,您使用的是静态变量。
为了得到我相信你想要的东西,你会这样做,就是这样。
(请注意,也不需要 Write-,因为在 PowerShell 中默认输出到屏幕。即使如此,也请避免使用 Write-Host,除了在有针对性的场景中,比如使用彩色屏幕输出。然而,即使那样,你也不需要它。有几个可以使用的 cmdlet,以及更灵活地获取颜色的方法。参见这些列出的 MS powershelgallery.com 模块)*
Find-Module -Name '*Color*'
调整您发布的代码,并结合 Ansgar Wiechers 向您展示的内容。
$ValidateSet = @('Banana','Apple','PineApple') # (Get-Content -Path 'E:\Temp\FruitValidationSet.txt')
function Test-LongValidateSet
{
[CmdletBinding()]
[Alias('tlfvs')]
Param
(
[Validatescript({
if ($ValidateSet -contains $PSItem) {$true}
else { throw $ValidateSet}})]
[String]$Fruit
)
"The selected fruit was: $Fruit"
}
# Results - will provide intellisense for the target $ValidateSet
Test-LongValidateSet -Fruit Apple
Test-LongValidateSet -Fruit Dog
# Results
The selected fruit was: Apple
# and on failure, spot that list out. So, you'll want to decide how to handle that
Test-LongValidateSet -Fruit Dog
Test-LongValidateSet : Cannot validate argument on parameter 'Fruit'. Banana Apple PineApple
At line:1 char:29
只需添加到文本数组/文件中,但这也意味着,该文件必须位于您使用此代码的每台主机上,或者至少能够达到 UNC 共享才能访问它。
现在,您可以使用其他文档"dynamic parameter validate set"。 Lee_Daily 指向查找,但要开始查找有点麻烦。
示例:
function Test-LongValidateSet
{
[CmdletBinding()]
[Alias('tlfvs')]
Param
(
# Any other parameters can go here
)
DynamicParam
{
# Set the dynamic parameters' name
$ParameterName = 'Fruit'
# Create the dictionary
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
# Create the collection of attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
# Create and set the parameters' attributes
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 1
# Add the attributes to the attributes collection
$AttributeCollection.Add($ParameterAttribute)
# Generate and set the ValidateSet
$arrSet = Get-Content -Path 'E:\Temp\FruitValidationSet.txt'
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
# Add the ValidateSet to the attributes collection
$AttributeCollection.Add($ValidateSetAttribute)
# Create and return the dynamic parameter
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
begin
{
# Bind the parameter to a friendly variable
$Fruit = $PsBoundParameters[$ParameterName]
}
process
{
# Your code goes here
$Fruit
}
}
# Results - provide intellisense for the target $arrSet
Test-LongValidateSet -Fruit Banana
Test-LongValidateSet -Fruit Cat
# Results
Test-LongValidateSet -Fruit Banana
Banana
Test-LongValidateSet -Fruit Cat
Test-LongValidateSet : Cannot validate argument on parameter 'Fruit'. The argument "Cat" does not belong to the set "Banana,Apple,PineApple"
specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.
At line:1 char:29
同样,只需将文本添加到文件中,同样,这也意味着该文件必须位于您使用此代码的每台主机上,或者至少能够访问 UNC 共享才能访问它.
我不确定您的具体用例是什么,但如果您使用的是 PowerShell 5.x 或更新版本,另一种可能性是创建一个 class,或者如果您正在使用对于旧版本,您可以在代码中嵌入一些 C# 来创建一个您可以使用的枚举:
Add-Type -TypeDefinition @"
public enum Fruit
{
Strawberry,
Orange,
Apple,
Pineapple,
Kiwi,
Blueberry,
Raspberry
}
"@
Function TestMe {
Param(
[Fruit]$Fruit
)
Write-Output $Fruit
}
我有一个具有很多高级功能的模块。 我需要使用一长串 ValidateSet 参数。 我想将可能参数的整个列表放在一个数组中,然后在函数本身中使用该数组。 如何从数组中提取整个集合的列表?
New-Variable -Name vars3 -Option Constant -Value @("Banana","Apple","PineApple")
function TEST123 {
param ([ValidateScript({$vars3})]
$Fruit)
Write-Host "$Fruit"
}
问题是,当我使用该函数时,它不会从常量中提取内容。
TEST123 -Fruit
如果我指定常量的索引值,它就可以工作。
TEST123 -Fruit $vars3[1]
它returns苹果。
你误解了 ValidateScript ...
ValidateScript Validation Attribute
The ValidateScript attribute specifies a script that is used to validate a parameter or variable value. PowerShell pipes the value to the script, and generates an error if the script returns $false or if the script throws an exception.
When you use the ValidateScript attribute, the value that is being validated is mapped to the $_ variable. You can use the $_ variable to refer to the value in the script.
...有效。正如其他人到目前为止所指出的那样。您没有使用脚本,您使用的是静态变量。
为了得到我相信你想要的东西,你会这样做,就是这样。
(请注意,也不需要 Write-,因为在 PowerShell 中默认输出到屏幕。即使如此,也请避免使用 Write-Host,除了在有针对性的场景中,比如使用彩色屏幕输出。然而,即使那样,你也不需要它。有几个可以使用的 cmdlet,以及更灵活地获取颜色的方法。参见这些列出的 MS powershelgallery.com 模块)*
Find-Module -Name '*Color*'
调整您发布的代码,并结合 Ansgar Wiechers 向您展示的内容。
$ValidateSet = @('Banana','Apple','PineApple') # (Get-Content -Path 'E:\Temp\FruitValidationSet.txt')
function Test-LongValidateSet
{
[CmdletBinding()]
[Alias('tlfvs')]
Param
(
[Validatescript({
if ($ValidateSet -contains $PSItem) {$true}
else { throw $ValidateSet}})]
[String]$Fruit
)
"The selected fruit was: $Fruit"
}
# Results - will provide intellisense for the target $ValidateSet
Test-LongValidateSet -Fruit Apple
Test-LongValidateSet -Fruit Dog
# Results
The selected fruit was: Apple
# and on failure, spot that list out. So, you'll want to decide how to handle that
Test-LongValidateSet -Fruit Dog
Test-LongValidateSet : Cannot validate argument on parameter 'Fruit'. Banana Apple PineApple
At line:1 char:29
只需添加到文本数组/文件中,但这也意味着,该文件必须位于您使用此代码的每台主机上,或者至少能够达到 UNC 共享才能访问它。
现在,您可以使用其他文档"dynamic parameter validate set"。 Lee_Daily 指向查找,但要开始查找有点麻烦。
示例:
function Test-LongValidateSet
{
[CmdletBinding()]
[Alias('tlfvs')]
Param
(
# Any other parameters can go here
)
DynamicParam
{
# Set the dynamic parameters' name
$ParameterName = 'Fruit'
# Create the dictionary
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
# Create the collection of attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
# Create and set the parameters' attributes
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 1
# Add the attributes to the attributes collection
$AttributeCollection.Add($ParameterAttribute)
# Generate and set the ValidateSet
$arrSet = Get-Content -Path 'E:\Temp\FruitValidationSet.txt'
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
# Add the ValidateSet to the attributes collection
$AttributeCollection.Add($ValidateSetAttribute)
# Create and return the dynamic parameter
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
begin
{
# Bind the parameter to a friendly variable
$Fruit = $PsBoundParameters[$ParameterName]
}
process
{
# Your code goes here
$Fruit
}
}
# Results - provide intellisense for the target $arrSet
Test-LongValidateSet -Fruit Banana
Test-LongValidateSet -Fruit Cat
# Results
Test-LongValidateSet -Fruit Banana
Banana
Test-LongValidateSet -Fruit Cat
Test-LongValidateSet : Cannot validate argument on parameter 'Fruit'. The argument "Cat" does not belong to the set "Banana,Apple,PineApple"
specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.
At line:1 char:29
同样,只需将文本添加到文件中,同样,这也意味着该文件必须位于您使用此代码的每台主机上,或者至少能够访问 UNC 共享才能访问它.
我不确定您的具体用例是什么,但如果您使用的是 PowerShell 5.x 或更新版本,另一种可能性是创建一个 class,或者如果您正在使用对于旧版本,您可以在代码中嵌入一些 C# 来创建一个您可以使用的枚举:
Add-Type -TypeDefinition @"
public enum Fruit
{
Strawberry,
Orange,
Apple,
Pineapple,
Kiwi,
Blueberry,
Raspberry
}
"@
Function TestMe {
Param(
[Fruit]$Fruit
)
Write-Output $Fruit
}