1

我有一个具有很多高级功能的模块。我需要使用一长串 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] 

它返回苹果。

4

2 回答 2

1

您误解了ValidateScript如何...

ValidateScript 验证属性

ValidateScript 属性指定用于验证参数或变量值的脚本。PowerShell 将值通过管道传递给脚本,如果脚本返回 $false 或脚本引发异常,则会生成错误。

当您使用 ValidateScript 属性时,正在验证的值将映射到 $_ 变量。您可以使用 $_ 变量来引用脚本中的值。

...有效。正如其他人迄今为止所指出的那样。您没有使用脚本,而是使用静态变量。

为了得到我相信你所追求的东西,你会这样做,这样。

(请注意,也不需要 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 共享以访问它。

现在,您可以使用其他记录在案的“动态参数验证集”。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 共享以访问它。

于 2019-05-14T03:15:53.367 回答
1

我不确定您的用例到底是什么,但如果您使用 PowerShell 5.x 或更新版本,另一种可能性是创建一个类,或者如果您使用的是旧版本,您可以在您的用于创建可以使用的 Enum 的代码:


Add-Type -TypeDefinition @"
   public enum Fruit
   {
      Strawberry,
      Orange,
      Apple,
      Pineapple,
      Kiwi,
      Blueberry,
      Raspberry
   }
"@

Function TestMe {
  Param(
    [Fruit]$Fruit
  )

  Write-Output $Fruit
}
于 2019-05-14T10:48:30.117 回答