Принятие необязательного параметра только как именованного, а не позиционного

Я пишу сценарий PowerShell, который является оболочкой для .exe. Я хочу иметь некоторые необязательные параметры сценария, а остальные передать непосредственно в exe. Вот тестовый скрипт:

param (
    [Parameter(Mandatory=$False)] [string] $a = "DefaultA"
   ,[parameter(ValueFromRemainingArguments=$true)][string[]]$ExeParams   # must be string[] - otherwise .exe invocation will quote
)

Write-Output ("a=" + ($a) + "  ExeParams:") $ExeParams

Если я запускаю с именованным параметром, все отлично:

C:\ > powershell /command \temp\a.ps1 -a A This-should-go-to-exeparams This-also
a=A  ExeParams:
This-should-go-to-exeparams
This-also

Однако, если я попытаюсь опустить свой параметр, ему будет назначен первый безымянный параметр:

C:\ > powershell /command \temp\a.ps1 This-should-go-to-exeparams This-also
a=This-should-go-to-exeparams  ExeParams:
This-also

я бы ожидал:

a=DefaultA ExeParams:
This-should-go-to-exeparams
This-also

Я попытался добавить Position=0 к параметру, но это дало тот же результат.

Есть ли способ добиться этого?
Может быть, другая схема параметров?


person Jonathan    schedule 11.06.2013    source источник


Ответы (2)


По умолчанию все параметры функции являются позиционными. Windows PowerShell присваивает номера позиций параметрам в том порядке, в котором параметры объявлены в функции. Чтобы отключить эту функцию, установите значение аргумента PositionalBinding атрибута CmdletBinding равным $False.

посмотрите at Как отключить привязку позиционного параметра в PowerShell

function Test-PositionalBinding
{
    [CmdletBinding(PositionalBinding=$false)]
    param(
       $param1,$param2
    )

    Write-Host param1 is: $param1
    Write-Host param2 is: $param2
}
person JPBlanc    schedule 11.06.2013
comment
Я не могу заставить это работать в Powershell 2.0 - это ожидается? - person bacar; 12.02.2014
comment
Я не думаю, что это работает в Powershell 2.0 (в сообщении в блоге говорится, что это не так, и ссылается на этого обходного пути) - person ernie; 26.08.2014

Основной ответ все еще работает в версии 5 (согласно комментариям, он мог быть некоторое время сломан в версии 2).

Есть еще вариант: добавить Position в параметр ValueFromRemainingArgs.

Образец CommandWrapper.ps1:

param(
    $namedOptional = "default",
    [Parameter(ValueFromRemainingArguments = $true, Position=1)]
    $cmdArgs
)

write-host "namedOptional: $namedOptional"
& cmd /c echo cmdArgs: @cmdArgs

Пример вывода:

>commandwrapper hello world
namedOptional: default
cmdArgs: hello world

Похоже, это следует из того, что PowerShell назначает позиции параметров из первого параметра с назначенной позицией.

person John Doggett    schedule 23.05.2019