1

请注意,示例代码是人为设计的,仅用于说明问题。

我想在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错误,但主要是如何解决这个问题?

4

1 回答 1

1

TheoJosefZ在对这个问题的评论中提供了关键的指示:

您试图将$minand$max参数位置传递给Get-Random,但Get-Random仅支持一个位置参数,即-Maximum参数。

因此,至少该$min值必须作为命名参数传递,即-Minimum $min您的命令在语法上工作。但是,为了对称性和可读性,最好也$max作为命名参数传递:

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

如何确定命令的位置参数:

about_Command_Syntax概念性帮助主题描述了 PowerShell 所谓的语法图中使用的符号。

要(仅)显示语法图,请使用Get-Command -Syntax(或 pass -?/ use 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>]- 它独立地表明参数作为一个整体是可选的(不是强制性的,即不需要传递参数)。

于 2021-01-07T18:19:20.033 回答