Как вы указываете как статические, так и динамические позиционные параметры в Powershell?

ИЗМЕНИТЬ

По предложению The Mad Technician я отправил отчет об ошибке на сайте PowerShell UserVoice: и-позиционные-параметры-не-делать-нет" rel="nofollow noreferrer"> https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/20034763-динамические-параметры-и-позиционные-параметры-не

ИСХОДНЫЙ ВОПРОС

Я хочу иметь возможность указывать позиционные параметры в функции PowerShell, которые включают как статические, так и динамические параметры. например У меня есть

function Test-Positional{
[CmdletBinding(PositionalBinding=$false)]
param(
    [Parameter(Mandatory=$false,Position=3)][string]$Param4
)
dynamicparam {
    $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary

    $paramname1 = "Param1"
    $values1 = 'some','list','of','values' #would normally get these dynamically
    $attributes1 = new-object System.Management.Automation.ParameterAttribute
    $attributes1.ParameterSetName = "__AllParameterSets"
    $attributes1.Mandatory = $true
    $attributes1.Position = 0
    $attributeCollection1 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection1.Add($attributes1)
    $ValidateSet1 = new-object System.Management.Automation.ValidateSetAttribute($values1)
    $attributeCollection1.Add($ValidateSet1)
    $dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname1, [string], $attributeCollection1)

    $paramname2 = "Param2"
    $values2 = 'another','list','like','before'
    $attributes2 = new-object System.Management.Automation.ParameterAttribute
    $attributes2.ParameterSetName = "__AllParameterSets"
    $attributes2.Mandatory = $true
    $attributes2.Position = 1
    $attributeCollection2 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection2.Add($attributes2)
    $ValidateSet2 = new-object System.Management.Automation.ValidateSetAttribute($values2)
    $attributeCollection2.Add($ValidateSet2)
    $dynParam2 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname2, [string], $attributeCollection2)

    $paramname3 = "Param3"
    $values3 = 'yet','another','list'
    $attributes3 = new-object System.Management.Automation.ParameterAttribute
    $attributes3.ParameterSetName = "__AllParameterSets"
    $attributes3.Mandatory = $true
    $attributes3.Position = 2
    $attributeCollection3 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection3.Add($attributes3)
    $ValidateSet3 = new-object System.Management.Automation.ValidateSetAttribute($values3)
    $attributeCollection3.Add($ValidateSet3)
    $dynParam3 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname3, [string], $attributeCollection3)

    $paramDictionary.Add($paramname1, $dynParam1)
    $paramDictionary.Add($paramname2, $dynParam2)
    $paramDictionary.Add($paramname3, $dynParam3)
    return $paramDictionary
}

process{
   $PSBoundParameters.Param1
   $PSBoundParameters.Param2
   $PSBoundParameters.Param3
   $PSBoundParameters.Param4
}
}

но если я запускаю PS C:\Windows\System32\inetsrv> Test-Positional 'list' 'another' 'yet' 'so', я получаю сообщение об ошибке:

Test-Positional: невозможно проверить аргумент параметра «Param1». Аргумент "другой" не принадлежит к набору "некоторые,список,значений", заданному атрибутом ValidateSet. Укажите аргумент из набора, а затем повторите команду. В строке: 1 char: 20 + Test-Positional список еще один + ~~~~~~~ + CategoryInfo : InvalidData: (:) [Test-Positional], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError, Test-Positional

Это не выдается, если я удаляю атрибут Position=3 из статического параметра ($ param4), что нормально, за исключением того, что я не могу использовать его в качестве позиционного параметра, я должен назвать его напрямую. Я получаю ту же ошибку, если сохраняю Position=3 и удаляю PositionalBinding=$false

Разве невозможно, чтобы и статические, и динамические параметры были позиционными параметрами? Или я пропустил что-то очевидное здесь?


person Micah Hunsberger    schedule 10.07.2017    source источник


Ответы (1)


Позиция работает по отношению к однотипным параметрам. Таким образом, статические параметры будут учитывать положение других статических параметров, а динамические параметры будут учитывать положение других динамических параметров, но статические параметры будут использовать аргументы в первую очередь, а динамические параметры будут использовать все, что осталось. Единственное исключение из этого, о котором я знаю, - это если вы используете атрибут параметра ValueFromRemainingArguments=$true, который заставляет этот конкретный параметр быть последним. Итак, если у вас действительно есть только 1 статический параметр, который вы хотите поставить после динамических параметров, вы можете установить ValueFromRemainingArguments=$true, и он будет вести себя так, как вы хотите. Если у вас есть другие статические параметры, они все равно будут стоять перед динамическими параметрами, независимо от того, укажете ли вы позицию позже, чем у динамических параметров.

Мне кажется, что вы нашли ошибку, и я рекомендую вам сообщить об этом на сайте PowerShell UserVoice: https://windowsserver.uservoice.com/forums/301869-powershell

На мой взгляд, они должны либо обновить документацию, чтобы указать, что позиционирование динамического параметра оценивается после позиционирования параметра stat, и исправить раздел синтаксиса, когда Get-Help запускается для функции/скрипта, либо соответствующим образом обновить поведение, чтобы позиции учитывались как в динамическом, так и в динамическом режиме. статические параметры. Я бы предпочел последнее, но это может потребовать замены двигателя, что невозможно.

Если вы создаете ошибку, предоставьте ссылку на нее, чтобы другие могли найти ее и проголосовать за нее (чтобы она привлекла внимание и была исправлена!).

person TheMadTechnician    schedule 10.07.2017