关于 Functions 高级参数

简短说明

说明如何将参数添加到高级函数。

长说明

可以将参数添加到写入的高级函数,并使用参数属性和参数来限制函数用户使用参数提交的参数值。

除了 PowerShell 自动添加到所有 cmdlet 和高级函数的常见参数之外,还可以向用户提供添加到函数的参数。 有关 PowerShell 常见参数的详细信息,请参阅 about_CommonParameters

从 PowerShell 3.0 开始,可以使用 splatting 来 @Args 表示命令中的参数。 Splatting 在简单和高级函数上有效。 有关详细信息,请参阅 about_Functionsabout_Splatting

参数值的类型转换

将字符串作为参数提供给需要不同类型的参数时,PowerShell 将字符串隐式转换为参数目标类型。 高级函数对参数值执行区域性固定分析。

相比之下,在编译的 cmdlet 的参数绑定期间执行区分区域性的转换。

在此示例中,我们将创建一个 cmdlet 和一个采用参数的 [datetime] 脚本函数。 当前区域性更改为使用德语设置。 德语格式的日期将传递给参数。

# Create a cmdlet that accepts a [datetime] argument.
Add-Type @'
  using System;
  using System.Management.Automation;
  [Cmdlet("Get", "Date_Cmdlet")]
  public class GetFooCmdlet : Cmdlet {

    [Parameter(Position=0)]
    public DateTime Date { get; set; }

    protected override void ProcessRecord() {
      WriteObject(Date);
    }
  }
'@ -PassThru | % Assembly | Import-Module

[cultureinfo]::CurrentCulture = 'de-DE'
$dateStr = '19-06-2018'

Get-Date_Cmdlet $dateStr
Dienstag, 19. Juni 2018 00:00:00

如上所示,cmdlet 使用区分区域性分析来转换字符串。

# Define an equivalent function.
function Get-Date_Func {
  param(
    [DateTime] $Date
  )
  process {
    $Date
  }
}

[cultureinfo]::CurrentCulture = 'de-DE'

# This German-format date string doesn't work with the invariant culture.
# E.g., [datetime] '19-06-2018' breaks.
$dateStr = '19-06-2018'

Get-Date_Func $dateStr

高级函数使用区域性固定分析,这会导致以下错误。

Get-Date_Func : Cannot process argument transformation on parameter 'Date'. Cannot convert
 value "19-06-2018" to type "System.DateTime". Error: "String was not recognized as a valid
 DateTime."
At line:13 char:15
+ Get-Date_Func $dateStr
+               ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Date_Func], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-Date_Func

静态参数

静态参数是函数中始终可用的参数。 PowerShell cmdlet 和脚本中的大多数参数都是静态参数。

以下示例显示了具有以下特征的 ComputerName 参数的声明:

  • 这是必需的 () 。
  • 它从管道获取输入。
  • 它采用字符串数组作为输入。
Param(
    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [String[]]
    $ComputerName
)

参数的属性

本部分介绍可添加到函数参数的属性。

所有特性都是可选的。 但是,如果省略 CmdletBinding 属性,则要识别为高级函数,则该函数必须包含 Parameter 属性。

可以在每个参数声明中添加一个或多个属性。 可以添加到参数声明的属性数没有限制。

参数属性

Parameter 属性用于声明函数参数的属性。

参数属性是可选的,如果函数的参数不需要属性,则可以省略它。 但是,若要识别为高级函数,而不是简单函数,函数必须具有 CmdletBinding 属性或 Parameter 属性,或同时具有这两者。

Parameter 属性具有定义参数特征的参数,例如参数是必需参数还是可选参数。

使用以下语法声明 Parameter 属性、参数和参数值。 将参数及其值括起来的括号必须遵循 参数 ,且没有干预空格。

Param(
    [Parameter(Argument=value)]
    $ParameterName
)

使用逗号分隔括号中的参数。 使用以下语法声明 Parameter 属性的两个参数。

Param(
    [Parameter(Argument1=value1,
    Argument2=value2)]
)

从 Parameter 属性省略时,Parameter 属性的布尔参数类型默认为 False 将参数值设置为 $true 或仅按名称列出参数。 例如,以下 参数 属性等效。

Param(
    [Parameter(Mandatory=$true)]
)

# Boolean arguments can be defined using this shorthand syntax

Param(
    [Parameter(Mandatory)]
)

如果使用 参数 属性而不带参数,作为使用 CmdletBinding 属性的替代方法,则仍需要遵循属性名称的括号。

Param(
    [Parameter()]
    $ParameterName
)

必需参数

Mandatory 参数指示参数是必需的。 如果未指定此参数,则参数是可选的。

以下示例声明 ComputerName 参数。 它使用 Mandatory 参数使参数是必需的。

Param(
    [Parameter(Mandatory=$true)]
    [String[]]
    $ComputerName
)

Position 参数

Position 参数确定在命令中使用参数时是否需要参数名称。 当参数声明包含 Position 参数时,可以省略参数名称,PowerShell 通过在命令中未命名的参数值列表中的位置或顺序来标识未命名的参数值。

Position如果未指定参数,则每当命令中使用参数时,参数名称或参数名称别名或缩写都必须在参数值之前。

默认情况下,所有函数参数都是位置参数。 PowerShell 按函数中声明参数的顺序将位置号分配给参数。 若要禁用此功能,请将 CmdletBinding 属性的参数的值PositionalBinding设置为 $False。 该Position参数优先于 CmdletBinding 属性的参数的值PositionalBinding。 有关详细信息,请参阅PositionalBindingabout_Functions_CmdletBindingAttribute

参数的值 Position 指定为整数。 位置值 0 表示命令中的第一个位置,位置值 1 表示命令中的第二个位置,依此表示。

如果函数没有位置参数,PowerShell 会根据声明参数的顺序为每个参数分配位置。 但是,作为最佳做法,不要依赖于此分配。 如果希望参数是位置参数,请使用 Position 参数。

以下示例声明 ComputerName 参数。 它使用 Position 值为 0 的参数。 因此,从命令中省略时 -ComputerName ,其值必须是命令中的第一个或仅未命名参数值。

Param(
    [Parameter(Position=0)]
    [String[]]
    $ComputerName
)

ParameterSetName 参数

ParameterSetName 参数指定参数所属的参数集。 如果未指定任何参数集,则参数属于函数定义的所有参数集。 因此,若要唯一,每个参数集必须至少有一个参数不是任何其他参数集的成员。

注意

对于 cmdlet 或函数,有 32 个参数集的限制。

以下示例在参数集中声明 ComputerName 参数Computer、参数集中的 UserUserName 参数和这两个参数集中的 Summary 参数。

Param(
    [Parameter(Mandatory=$true,
    ParameterSetName="Computer")]
    [String[]]
    $ComputerName,

    [Parameter(Mandatory=$true,
    ParameterSetName="User")]
    [String[]]
    $UserName,

    [Parameter(Mandatory=$false)]
    [Switch]
    $Summary
)

在每个参数中只能指定一个ParameterSetName值,每个 Parameter 属性中只能指定一个ParameterSetName参数。 若要指示参数出现在多个参数集中,请添加其他 Parameter 属性。

以下示例将 Summary 参数显式添加到 ComputerUser 参数集。 摘要参数在参数集中是可选的Computer,在参数集中是必需的User

Param(
    [Parameter(Mandatory=$true,
    ParameterSetName="Computer")]
    [String[]]
    $ComputerName,

    [Parameter(Mandatory=$true,
    ParameterSetName="User")]
    [String[]]
    $UserName,

    [Parameter(Mandatory=$false, ParameterSetName="Computer")]
    [Parameter(Mandatory=$true, ParameterSetName="User")]
    [Switch]
    $Summary
)

有关参数集的详细信息,请参阅 “关于参数集”。

ValueFromPipeline 参数

ValueFromPipeline 参数指示参数接受管道对象的输入。 如果函数接受整个对象,而不仅仅是对象的属性,请指定此参数。

以下示例声明一个 ComputerName 参数,该参数是必需的,并接受从管道传递到函数的对象。

Param(
    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [String[]]
    $ComputerName
)

ValueFromPipelineByPropertyName 参数

ValueFromPipelineByPropertyName 参数指示参数接受管道对象的属性的输入。 对象属性必须与参数具有相同的名称或别名。

例如,如果函数具有 ComputerName 参数,并且管道对象具有 ComputerName 属性,则 ComputerName 属性的值将分配给函数的 ComputerName 参数。

下面的示例声明一个 ComputerName 参数,该参数是必需的,并接受通过管道传递给函数的对象 ComputerName 属性的输入。

Param(
    [Parameter(Mandatory=$true,
    ValueFromPipelineByPropertyName=$true)]
    [String[]]
    $ComputerName
)

注意

接受管道输入的类型化参数 (by Value) 或 () by PropertyName 允许对参数使用 延迟绑定 脚本块。

延迟绑定脚本块在 ParameterBinding 期间自动运行。 结果绑定到参数。 延迟绑定不适用于定义为类型 ScriptBlockSystem.Object. 脚本块在 未调用的情况下 传递。

可以在此处about_Script_Blocks.md 阅读有关延迟绑定脚本块的信息。

ValueFromRemainingArguments 参数

ValueFromRemainingArguments 参数指示参数接受命令中未分配给函数的其他参数的所有参数值。

以下示例 声明一个 值参数,该参数是必需的,以及接受提交到函数的所有剩余参数值的 Remaining 参数。

function Test-Remainder
{
     param(
         [string]
         [Parameter(Mandatory = $true, Position=0)]
         $Value,
         [string[]]
         [Parameter(Position=1, ValueFromRemainingArguments)]
         $Remaining)
     "Found $($Remaining.Count) elements"
     for ($i = 0; $i -lt $Remaining.Count; $i++)
     {
        "${i}: $($Remaining[$i])"
     }
}
Test-Remainder first one,two
Found 2 elements
0: one
1: two

注意

在 PowerShell 6.2 之前, ValueFromRemainingArguments 集合联接为索引 0 下的单个实体。

HelpMessage 参数

HelpMessage 参数指定一个字符串,其中包含参数或其值的简短说明。 PowerShell 在命令中缺少强制参数值时出现的提示中显示此消息。 此参数对可选参数无效。

以下示例声明必需的 ComputerName 参数和说明预期参数值的帮助消息。

例如,如果函数没有其他 基于注释的帮助 语法 (, .SYNOPSIS) 则此消息也会显示在输出中 Get-Help

Param(
    [Parameter(Mandatory=$true,
    HelpMessage="Enter one or more computer names separated by commas.")]
    [String[]]
    $ComputerName
)

Alias 特性

Alias 属性为参数建立备用名称。 可以分配给参数的别名数没有限制。

以下示例演示了一个参数声明,该声明将 CNMachineName 别名添加到必需的 ComputerName 参数。

Param(
    [Parameter(Mandatory=$true)]
    [Alias("CN","MachineName")]
    [String[]]
    $ComputerName
)

SupportsWildcards 属性

SupportsWildcards 属性用于指示参数接受通配符值。 以下示例演示支持通配符值的必需 Path 参数的参数声明。

Param(
    [Parameter(Mandatory=$true)]
    [SupportsWildcards()]
    [String[]]
    $Path
)

使用此属性不会自动启用通配符支持。 cmdlet 开发人员必须实现代码来处理通配符输入。 支持的通配符可能因基础 API 或 PowerShell 提供程序而异。 有关详细信息,请参阅 about_Wildcards

参数和变量验证属性

验证属性指示 PowerShell 测试用户在调用高级函数时提交的参数值。 如果参数值测试失败,则会生成错误,并且不会调用该函数。 参数验证仅适用于提供的输入,并且不会验证任何其他值(如默认值)。

还可以使用验证属性来限制用户可以为变量指定的值。 将类型转换器与验证属性一起使用时,必须在属性之前定义类型转换器。

[int32][AllowNull()] $number = 7

AllowNull 验证属性

AllowNull 属性允许强制参数的值。$null 以下示例声明一个可具有 null 值的哈希表 ComputerInfo 参数。

Param(
    [Parameter(Mandatory=$true)]
    [AllowNull()]
    [hashtable]
    $ComputerInfo
)

注意

如果类型转换器设置为字符串,则 AllowNull 属性不起作用,因为字符串类型不接受 null 值。 可以将 AllowEmptyString 属性用于此方案。

AllowEmptyString 验证属性

AllowEmptyString 属性允许强制参数的值作为空字符串 ("") 。 以下示例声明一个可具有空字符串值的 ComputerName 参数。

Param(
    [Parameter(Mandatory=$true)]
    [AllowEmptyString()]
    [String]
    $ComputerName
)

AllowEmptyCollection 验证属性

AllowEmptyCollection 属性允许强制参数的值为空集合@()。 以下示例声明一个可具有空集合值的 ComputerName 参数。

Param(
    [Parameter(Mandatory=$true)]
    [AllowEmptyCollection()]
    [String[]]
    $ComputerName
)

ValidateCount 验证属性

ValidateCount 属性指定参数接受的最小和最大参数值数。 如果调用函数的命令中的参数值数超出该范围,PowerShell 将生成错误。

以下参数声明创建一个 ComputerName 参数,该参数采用一到五个参数值。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateCount(1,5)]
    [String[]]
    $ComputerName
)

ValidateLength 验证属性

ValidateLength 属性指定参数或变量值中的最小和最大字符数。 如果为参数或变量指定的值长度超出范围,PowerShell 将生成错误。

在下面的示例中,每个计算机名称必须有一到十个字符。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateLength(1,10)]
    [String[]]
    $ComputerName
)

在以下示例中,变量 $number 的值必须至少为长度为一个字符,最大长度为 10 个字符。

[Int32][ValidateLength(1,10)]$number = '01'

注意

在此示例中,值 01 用单引号包装。 ValidateLength 属性不接受数字,而不用引号包装。

ValidatePattern 验证属性

ValidatePattern 属性指定与参数或变量值进行比较的正则表达式。 如果值与正则表达式模式不匹配,PowerShell 将生成错误。

在下面的示例中,参数值必须包含一个四位数的数字,每个数字必须是零到九个数字。

Param(
    [Parameter(Mandatory=$true)]
    [ValidatePattern("[0-9][0-9][0-9][0-9]")]
    [String[]]
    $ComputerName
)

在下面的示例中,变量 $number 的值必须是四位数数字,每个数字必须是数字零到 9。

[Int32][ValidatePattern("^[0-9][0-9][0-9][0-9]$")]$number = 1111

ValidateRange 验证属性

ValidateRange 属性为每个参数或变量值指定数值范围或 ValidateRangeKind 枚举值。 如果任何值超出该范围,PowerShell 将生成错误。

ValidateRangeKind 枚举允许以下值:

  • - 大于零的数字。
  • 数 - 小于零的数字。
  • 非Positive - 小于或等于零的数字。
  • 非负 数 - 大于或等于零的数字。

在下面的示例中, Attempts 参数的值必须介于零到 10 之间。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateRange(0,10)]
    [Int]
    $Attempts
)

在下面的示例中,变量 $number 的值必须介于零到 10 之间。

[Int32][ValidateRange(0,10)]$number = 5

在以下示例中,变量 $number 的值必须大于零。

[Int32][ValidateRange("Positive")]$number = 1

ValidateScript 验证属性

ValidateScript 属性指定用于验证参数或变量值的脚本。 PowerShell 通过管道将值传递给脚本,并在脚本返回 $false 时或脚本引发异常时生成错误。

使用 ValidateScript 属性时,要验证的值将 $_ 映射到变量。 可以使用 $_ 变量来引用脚本中的值。

在以下示例中, EventDate 参数的值必须大于或等于当前日期。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateScript({$_ -ge (Get-Date)})]
    [DateTime]
    $EventDate
)

在以下示例中,变量 $date 的值必须大于或等于当前日期和时间。

[DateTime][ValidateScript({$_ -ge (Get-Date)})]$date = (Get-Date)

注意

如果使用 ValidateScript,则无法将 $null 值传递给参数。 传递 null 值 ValidateScript 时,无法验证参数。

ValidateSet 属性

ValidateSet 属性指定参数或变量的一组有效值,并启用选项卡完成。 如果参数或变量值与集中的值不匹配,PowerShell 将生成错误。 在以下示例中, Detail 参数的值只能为“低”、“平均值”或“高”。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateSet("Low", "Average", "High")]
    [String[]]
    $Detail
)

在以下示例中,变量 $flavor 的值必须是 Chocolate、Strawberry 或 Vanilla。

[ValidateSet("Chocolate", "Strawberry", "Vanilla")]
[String]$flavor = "Strawberry"

每当在脚本中分配该变量时,也会进行验证。 例如,以下结果在运行时出错:

Param(
    [ValidateSet("hello", "world")]
    [String]$Message
)

$Message = "bye"

动态 validateSet 值

可以使用 在运行时动态生成 ValidateSet 的值。 在以下示例中,变量$Sound的有效值通过名为 SoundNames 的类生成,该检查三个文件系统路径以获取可用的声音文件:

Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
    [String[]] GetValidValues() {
        $SoundPaths = '/System/Library/Sounds/',
            '/Library/Sounds','~/Library/Sounds'
        $SoundNames = ForEach ($SoundPath in $SoundPaths) {
            If (Test-Path $SoundPath) {
                (Get-ChildItem $SoundPath).BaseName
            }
        }
        return [String[]] $SoundNames
    }
}

然后,类 [SoundNames] 作为动态 ValidateSet 值实现,如下所示:

Param(
    [ValidateSet([SoundNames])]
    [String]$Sound
)

ValidateNotNull 验证属性

ValidateNotNull 属性指定参数值不能 $null。 如果参数值为 $null.,PowerShell 将生成错误。

ValidateNotNull 属性设计为可选参数且类型未定义或具有无法隐式转换 null 值(如对象)的类型转换器时使用。 如果指定将隐式转换 null 值(如 字符串)的类型,即使使用 ValidateNotNull 属性,null 值也会转换为空字符串。 对于此方案,请使用 ValidateNotNullOrEmpty

在以下示例中, ID 参数的值不能 $null为 。

Param(
    [Parameter(Mandatory=$false)]
    [ValidateNotNull()]
    $ID
)

ValidateNotNullOrEmpty 验证属性

ValidateNotNullOrEmpty 属性指定参数值不能$null且不能是空字符串 ("") 。 如果在函数调用中使用参数,但其值为 $null空字符串 ("") 或空数组 @(),则 PowerShell 将生成错误。

Param(
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [String[]]
    $UserName
)

ValidateDrive 验证属性

ValidateDrive 属性指定参数值必须表示仅引用允许驱动器的路径。 如果参数值引用了允许的驱动器,则 PowerShell 将生成错误。 路径的存在(驱动器本身除外)未验证。

如果使用相对路径,则当前驱动器必须位于允许的驱动器列表中。

Param(
    [ValidateDrive("C", "D", "Variable", "Function")]
    [String]$Path
)

ValidateUserDrive 验证属性

ValidateUserDrive 属性指定参数值必须表示引用User驱动器的路径。 如果路径引用其他驱动器,PowerShell 将生成错误。 验证属性仅测试路径的驱动器部分是否存在。

如果使用相对路径,则当前驱动器必须为 User

function Test-UserDrivePath{
    [OutputType([bool])]
    Param(
      [Parameter(Mandatory=, Position=0)][ValidateUserDrive()][String]$Path
      )
    $True
}

Test-UserDrivePath -Path C:\
Test-UserDrivePath: Cannot validate argument on parameter 'Path'. The path
argument drive C does not belong to the set of approved drives: User.
Supply a path argument with an approved drive.
Test-UserDrivePath -Path 'User:\A_folder_that_does_not_exist'
Test-UserDrivePath: Cannot validate argument on parameter 'Path'. Cannot
find drive. A drive with the name 'User' does not exist.

可以在 Just Enough Administration (JEA) 会话配置中定义 User 驱动器。 在本示例中,我们将创建用户:驱动器。

New-PSDrive -Name 'User' -PSProvider FileSystem -Root $env:HOMEPATH
Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
User               75.76         24.24 FileSystem    C:\Users\ExampleUser

```powershell
Test-UserDrivePath -Path 'User:\A_folder_that_does_not_exist'
True

ValidateTrustedData 验证属性

此属性已在 PowerShell 6.1.1 中添加。

目前,特性由 PowerShell 本身在内部使用,不用于外部使用。

动态参数

动态参数是仅在某些条件下可用的 cmdlet、函数或脚本的参数。

例如,多个提供程序 cmdlet 具有仅在提供程序驱动器中使用 cmdlet 或提供程序驱动器的特定路径时可用的参数。 例如,仅在文件系统驱动器中使用编码参数时,才可在 Add-ContentGet-ContentSet-Content cmdlet 上使用。

还可以创建仅在函数命令中使用另一个参数或另一个参数具有特定值时显示的参数。

动态参数非常有用,但仅在必要时才使用这些参数,因为用户很难发现它们。 若要查找动态参数,用户必须位于提供程序路径中、使用 cmdlet 的 Get-CommandArgumentList 参数或使用 Path 参数Get-Help

若要为函数或脚本创建动态参数,请使用 DynamicParam 关键字。

语法如下:

DynamicParam {<statement-list>}

在语句列表中,使用语句 If 指定函数中可用参数的条件。

使用 New-Object cmdlet 创建 System.Management.Automation.RuntimeDefinedParameter 对象来表示参数并指定其名称。

可以使用 New-Object 命令创建 System.Management.Automation.ParameterAttribute 对象来表示参数的属性,例如 必需位置ValueFromPipeline 或其参数集。

以下示例演示一个示例函数,其中包含名为 NamePath 的标准参数,以及名为 DP1 的可选动态参数。 DP1 参数位于PSet1参数集中,类型为 Int32. 仅当 Path 参数的值开始时HKLM:DP1 参数Get-Sample才可用于函数,指示它在注册表驱动器中使用HKEY_LOCAL_MACHINE

function Get-Sample {
  [CmdletBinding()]
  Param([String]$Name, [String]$Path)

  DynamicParam
  {
    if ($Path.StartsWith("HKLM:"))
    {
      $attributes = New-Object -Type `
        System.Management.Automation.ParameterAttribute
      $attributes.ParameterSetName = "PSet1"
      $attributes.Mandatory = $false
      $attributeCollection = New-Object `
        -Type System.Collections.ObjectModel.Collection[System.Attribute]
      $attributeCollection.Add($attributes)

      $dynParam1 = New-Object -Type `
        System.Management.Automation.RuntimeDefinedParameter("DP1", [Int32],
          $attributeCollection)

      $paramDictionary = New-Object `
        -Type System.Management.Automation.RuntimeDefinedParameterDictionary
      $paramDictionary.Add("DP1", $dynParam1)
      return $paramDictionary
    }
  }
}

有关详细信息,请参阅 RuntimeDefinedParameter

开关参数

开关参数是没有参数值的参数。 它们仅在使用时才有效,并且只有一个效果。

例如,powershell.exeNoProfile 参数是开关参数。

若要在函数中创建 switch 参数,请在 Switch 参数定义中指定类型。

例如:

Param([Switch]<ParameterName>)

或者,可以使用另一种方法:

Param(
    [Parameter(Mandatory=$false)]
    [Switch]
    $<ParameterName>
)

开关参数易于使用,首选于布尔参数,具有更困难的语法。

例如,若要使用 switch 参数,用户键入命令中的参数。

-IncludeAll

若要使用布尔参数,用户键入参数和布尔值。

-IncludeAll:$true

创建开关参数时,请仔细选择参数名称。 请确保参数名称将参数的效果传达给用户。 避免含糊不清的术语,例如可能暗示需要值的 筛选器最大值

ArgumentCompleter 属性

ArgumentCompleter 属性允许向特定参数添加选项卡完成值。 必须为需要选项卡完成的每个参数定义 ArgumentCompleter 属性。 与 DynamicParameters 类似,当用户在参数名称后面按 Tab 时,将在运行时计算可用值。

若要添加 ArgumentCompleter 属性,需要定义确定值的脚本块。 脚本块必须按下面指定的顺序采用以下参数。 参数的名称并不重要,因为值以位置提供。

语法如下:

Param(
    [Parameter(Mandatory)]
    [ArgumentCompleter({
        param ( $commandName,
                $parameterName,
                $wordToComplete,
                $commandAst,
                $fakeBoundParameters )
        # Perform calculation of tab completed values here.
    })]
)

ArgumentCompleter 脚本块

脚本块参数设置为以下值:

  • $commandName (位置 0) - 此参数设置为脚本块提供选项卡完成的命令的名称。
  • $parameterName (Position 1) - 此参数设置为其值需要选项卡完成的参数。
  • $wordToComplete (Position 2) - 此参数设置为用户在按下 Tab 之前提供的值。脚本块应使用此值来确定选项卡完成值。
  • $commandAst (位置 3) - 此参数设置为当前输入行的“抽象语法树” (AST) 。 有关详细信息,请参阅 Ast 类
  • $fakeBoundParameters (Position 4) - 在用户按下 Tab 之前,此参数设置为包含 $PSBoundParameters cmdlet 的哈希 。有关详细信息,请参阅 about_Automatic_Variables

ArgumentCompleter 脚本块必须使用管道(例如ForEach-ObjectWhere-Object,或其他合适的方法)取消注册值。 返回值数组会导致 PowerShell 将整个数组视为 一个 选项卡完成值。

以下示例将 Tab 完成添加到 Value 参数。 如果仅指定 Value 参数,则会显示 Value 的所有可能值或参数。 指定 Type 参数时, Value 参数仅显示该类型的可能值。

此外, -like 操作员可确保如果用户键入以下命令并使用 Tab 完成,则仅返回 Apple

Test-ArgumentCompleter -Type Fruits -Value A

function Test-ArgumentCompleter {
[CmdletBinding()]
 param (
        [Parameter(Mandatory=$true)]
        [ValidateSet('Fruits', 'Vegetables')]
        $Type,
        [Parameter(Mandatory=$true)]
        [ArgumentCompleter( {
            param ( $commandName,
                    $parameterName,
                    $wordToComplete,
                    $commandAst,
                    $fakeBoundParameters )

            $possibleValues = @{
                Fruits = @('Apple', 'Orange', 'Banana')
                Vegetables = @('Tomato', 'Squash', 'Corn')
            }
            if ($fakeBoundParameters.ContainsKey('Type'))
            {
                $possibleValues[$fakeBoundParameters.Type] | Where-Object {
                    $_ -like "$wordToComplete*"
                }
            }
            else
            {
                $possibleValues.Values | ForEach-Object {$_}
            }
        } )]
        $Value
      )
}

请参阅

about_Automatic_Variables

about_Functions

about_Functions_Advanced

about_Functions_Advanced_Methods

about_Functions_CmdletBindingAttribute

about_Functions_OutputTypeAttribute