Powershell Не удается найти позиционный параметр, который принимает аргумент «10». Даже не используя позиционный параметр

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

Я хотел создать функцию в powershell для получения случайных чисел, но столкнулся с очень странной проблемой: когда я не использую определение позиции параметра, я все равно получаю сообщение об ошибке.

Мой код:

function select-random {

  param(
    [Parameter(Position = 0, Mandatory)]
    [int]$min,
    [Parameter(Position = 1, Mandatory)]
    [int]$max
  )

  Get-Random $min $max

}

Ошибка, которую этот скрипт получает с командой: select-random 5 10

A positional parameter cannot be found that accepts argument '10'.

И командой: select-random -min 5 -max 10

A positional parameter cannot be found that accepts argument '10'.`

Самое странное, что ISE обнаруживает параметр, определенный вручную, в меню вкладок.

Мой синтаксис неправильный или это ошибка powershell, но в основном как это исправить?


person smvd    schedule 06.01.2021    source источник
comment
Вы определяете параметры как [int], но обрабатываете их как строки ("")... Кроме того, параметр Minimum является только Именованным, тогда как первый позиционный параметр должен быть Maximum. Лучшее название обоих параметров на Get-Random   -  person Theo    schedule 06.01.2021
comment
Внимательно прочитайте сообщение об ошибке: Get-Random : не удается найти позиционный параметр… Используйте get-random -Minimum $min -Maximum $max в строке № 11.   -  person JosefZ    schedule 06.01.2021


Ответы (1)


Тео и Джозеф З предоставил важные указатели в комментариях к вопросу:

Вы пытаетесь передать аргументы $min и $max позиционно в Get-Random, однако Get-Random поддерживает только один позиционный аргумент, а именно для параметра -Maximum.

Таким образом, по крайней мере значение $min должно быть передано в качестве аргумента named, то есть как -Minimum $min, чтобы ваша команда работала синтаксически. Однако для симметрии и удобочитаемости лучше также передавать $max в качестве именованного аргумента:

# Use *named* arguments.
Get-Random -Minimum $min -Maximum $max

Как определить позиционные аргументы команды:

В разделе концептуальной справки about_Command_Syntax описывается нотация, используемая в так называемых синтаксических диаграммах PowerShell.

Чтобы отобразить синтаксические диаграммы (только), используйте Get-Command -Syntax (или передайте -? / используйте Get-Help, что показывает дополнительную информацию):

PS> & { Get-Command -Syntax $args[0] } Get-Random

Get-Random [[-Maximum] <Object>] [-SetSeed <int>] [-Minimum <Object>] [-Count <int>] [<CommonParameters>]

Get-Random [-InputObject] <Object[]> -Shuffle [-SetSeed <int>] [<CommonParameters>]

Get-Random [-InputObject] <Object[]> [-SetSeed <int>] [-Count <int>] [<CommonParameters>]

Только параметры, только имена которых заключены в [...][1], являются позиционными — например, [-Maximum] — и, если поддерживается несколько, они перечислены в том порядке, в котором должны передаваться при вызове.

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

Как видите, только -Maximum является позиционным в первом наборе параметров, а -Minimum и все остальные параметры - нет.


Вот вспомогательная функция Get-PositionalParameter, упрощающая определение позиционных параметров команды:

Function Get-PositionalParameter {
<#
.SYNOPSIS
Outputs a given command's positional parameters, if any.
#>
  param(
    [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
    [string] $Name
  )
  Set-StrictMode -Version 1; $ErrorActionPreference = 'Stop'
  # Resolve the name to a cmdlet first, if necessary
  $cmd = (Get-Command $Name)
  if ($cmd.ResolvedCommand) { $cmd = $cmd.ResolvedCommand }

  $cmd.ParameterSets | ForEach-Object {
    if ($posParams = $_.Parameters.Where( { $_.Position -ge 0 })) {
      [pscustomobject] @{
        PositionalParams = $posParams.Name
        ParameterSet     = $_.Name
      }
    }
  }
}

Применяется к Get-Random:

PS> Get-PositionalParameter Get-Random

PositionalParams ParameterSet
---------------- ------------
Maximum          RandomNumberParameterSet
InputObject      ShuffleParameterSet
InputObject      RandomListItemParameterSet

Обратите внимание, что названия набора параметров не отображаются в разделах справки и при использовании Get-Command -Syntax, потому что на самом деле они не предназначены для общественного отображения, но их имена обычно описательные. достаточно, чтобы понять их назначение.


[1] Сравните это со спецификацией параметра в целом, заключенной в [...] — например. [-Minimum <Object>] — что независимо указывает на то, что параметр в целом является необязательным (не обязательным, т. е. передача аргумента не требуется).

person mklement0    schedule 07.01.2021