Как получить параметр валидации скрипта Powershell, извлекаемый из массива? - PullRequest
1 голос
/ 13 мая 2019

У меня есть модуль с множеством расширенных функций. Мне нужно использовать длинный список параметров 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] 

Возвращает Apple.

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Я не совсем уверен, каков ваш вариант использования, но другая возможность, если вы используете PowerShell 5.x или новее, - это создать класс или если вы используете более старую версию, вы можете немного встроитьC # в вашем коде для создания Enum, который вы можете использовать:


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

Function TestMe {
  Param(
    [Fruit]$Fruit
  )

  Write-Output $Fruit
}
1 голос
/ 14 мая 2019

Вы неправильно понимаете, как ValidateScript ...

Атрибут проверки ValidateScript

Атрибут ValidateScript указывает сценарий, который используется для проверки параметра или переменнойзначение.PowerShell передает значение в сценарий и выдает ошибку, если сценарий возвращает значение $ false или сценарий создает исключение.

При использовании атрибута ValidateScript проверяемое значение сопоставляется с $.переменнаяВы можете использовать переменную $ _ для ссылки на значение в скрипте.

... работает.Как уже указывали другие.Вы не используете скрипт, вы используете статическую переменную.

Чтобы получить то, что, как я полагаю, вам нужно, вы бы сделали это таким образом.

(Обратите внимание, что Write- также не требуется, поскольку вывод на экран по умолчанию в PowerShell. По умолчанию избегайте использования Write-Host, кроме как в целевых сценариях, таких какиспользование вывода на цветной экран. Но даже в этом случае он вам и не нужен. Существует несколько командлетов, которые можно использовать, и способы получения цвета с большей гибкостью. См. перечисленные модули MS powershelgallery.com) *

Find-Module -Name '*Color*'

Настройка вашего кода, который вы опубликовали, и включение того, что показывает вам Ансгар Вичерс.

$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.

...