about_Functions_Advanced_Parameters

简短说明

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

长说明

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

除了 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 '19-06-2018' was not recognized as a valid DateTime."

静态参数

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

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

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

开关参数

开关参数是不采用参数值的参数。 相反,它们通过存在或不存在来传达布尔值 true-or-false 值,以便当 switch 参数存在时,它具有 true 值,如果不存在,则具有 false 值。

例如,的 Get-ChildItemRecurse 参数是 switch 参数。

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

例如,函数可以选择将数据输出为字节数组:

param([switch]$AsByteArray)

Switch 参数易于使用,优先于布尔参数,后者的 PowerShell 语法不太自然。

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

-IncludeAll

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

-IncludeAll $true

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

开关参数设计注意事项

  • 不应为开关参数提供默认值。 它们应始终默认为 false。

  • 默认情况下,开关参数从位置参数中排除。 即使其他参数是隐式位置参数,开关参数也不会。 可以在 Parameter 属性中替代该属性,但它会使用户感到困惑。

  • 应设计开关参数,以便设置它们可将命令从其默认行为移动到不太常见或更复杂的模式。 命令的最简单行为应该是不需要使用开关参数的默认行为。

  • 不应强制使用开关参数。 必须强制使用 switch 参数的唯一情况是需要区分参数集。

  • 使用 显式设置布尔值中的开关,并在使用 展开$params = @{ MySwitch = $boolValue }时完成-MySwitch:$boolValue

  • 开关参数的类型 SwitchParameter为 ,可隐式转换为布尔值。 参数变量可以直接在条件表达式中使用。 例如:

    if ($MySwitch) { ... }

    无需编写 if ($MySwitch.IsPresent) { ... }

动态参数

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

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

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

动态参数可能很有用,但仅在必要时使用它们,因为用户可能难以发现它们。 若要查找动态参数,用户必须位于提供程序路径中,使用 cmdlet 的 Get-CommandArgumentList 参数或使用 的 Get-HelpPath 参数。

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

语法如下所示:

dynamicparam {<statement-list>}

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

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

function Get-Sample {
  [CmdletBinding()]
  param([string]$Name, [string]$Path)

  DynamicParam
  {
    if ($Path.StartsWith("HKLM:"))
    {
      $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{
          ParameterSetName = "ByRegistryPath"
          Mandatory = $false
      }

      $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
      $attributeCollection.Add($parameterAttribute)

      $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new(
        'KeyCount', [Int32], $attributeCollection
      )

      $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
      $paramDictionary.Add('KeyCount', $dynParam1)
      return $paramDictionary
    }
  }
}

有关详细信息,请参阅 RuntimeDefinedParameter 类型的文档。

参数的属性

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

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

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

参数属性

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

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

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

使用以下语法声明 Parameter 属性、参数和参数值。 将参数及其值括起来的括号必须跟在 Parameter 后面,且没有中间空格。

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

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

param(
    [Parameter(Argument1=value1, Argument2=value2)]
    $ParameterName
)

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

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

# Boolean arguments can be defined using this shorthand syntax

param(
    [Parameter(Mandatory)]
)

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

param(
    [Parameter()]
    $ParameterName
)

必需参数

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

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

param(
    [Parameter(Mandatory)]
    [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 个参数集的限制。

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

param(
    [Parameter(Mandatory, ParameterSetName="Computer")]
    [string[]]$ComputerName,

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

    [Parameter()]
    [switch]$Summary
)

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

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

param(
    [Parameter(Mandatory, ParameterSetName="Computer")]
    [string[]]$ComputerName,

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

    [Parameter(ParameterSetName="Computer")]
    [Parameter(Mandatory, ParameterSetName="User")]
    [switch]$Summary
)

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

ValueFromPipeline 参数

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

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

param(
    [Parameter(Mandatory, ValueFromPipeline)]
    [string[]]$ComputerName
)

ValueFromPipelineByPropertyName 参数

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

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

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

param(
    [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName
)

请考虑使用此参数实现函数:

function Test-ValueFromPipelineByPropertyName{
  param(
      [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
      [string[]]$ComputerName
  )
  Write-Output -InputObject "Saw that ComputerName was '$ComputerName'"
}

然后,使用 ComputerName 属性管道对象的演示将是:

[pscustomobject]@{ ComputerName = "HelloWorld" } |
    Test-ValueFromPipelineByPropertyName
Saw that ComputerName was 'HelloWorld'

注意

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

延迟绑定脚本块在 ParameterBinding 期间自动运行。 结果绑定到 参数。 延迟绑定不适用于定义为 ScriptBlockSystem.Object 类型的参数。 脚本块在不调用 的情况下 传递。 有关 延迟绑定 脚本块的详细信息,请参阅 about_Script_Blocks

ValueFromRemainingArguments 参数

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

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

function Test-Remainder {
    param(
        [Parameter(Mandatory, Position=0)]
        [string]$Value,

        [Parameter(Position=1, ValueFromRemainingArguments)]
        [string[]]$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

HelpMessage 参数

参数 HelpMessage 指定一个字符串,其中包含参数或其值的简短说明。 如果在不使用必需参数的情况下运行命令,PowerShell 会提示你输入。 若要查看帮助消息,请在提示符处键入 !? 并点击 Enter

下面的示例声明一个必需的 ComputerName 参数和一个帮助消息,用于解释预期的参数值。

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

示例输出:

cmdlet  at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
ComputerName[0]: !?
Enter one or more computer names separated by commas.
ComputerName[0]: localhost
ComputerName[1]:

如果函数没有 基于注释的帮助 ,则输出中 Get-Help -Full 会显示此消息。

此参数对可选参数没有影响。

Alias 特性

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

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

param(
    [Parameter(Mandatory)]
    [Alias("CN","MachineName")]
    [string[]]$ComputerName
)

Credential 属性

Credential 属性用于指示 参数接受凭据。 以下示例演示使用 Credential 属性的参数声明。

param(
    [Parameter()]
    [System.Management.Automation.Credential()]
    [PSCredential]$Credential
)

试验属性

使用 实验 属性将某些代码声明为试验性代码。 有关属性的完整说明,请参阅 about_Experimental_Features

PSDefaultValue 属性

PSDefaultValue 指定脚本中命令参数的默认值。 此信息由 Get-Help cmdlet 显示。 若要查看默认值信息,函数必须包含基于注释的帮助。 例如:

<#
    .SYNOPSIS
     This is a test script that has a parameter with a default value.
#>
function TestDefaultValue {
    param(
        [PSDefaultValue(Help='Current directory')]
        [string]$Name = $PWD.Path
    )

    $Name
}

使用 Get-Help 查看默认值信息。

Get-Help TestDefaultValue -Parameter name
-Name <String>

    Required?                    false
    Position?                    1
    Default value                Current directory
    Accept pipeline input?       false
    Accept wildcard characters?  false

PSDefaultValue 属性参数

PSDefaultValue 属性有两个参数:

  • 帮助 - 描述默认值的字符串。 此信息由 Get-Help cmdlet 显示。
  • - 参数的默认值。

这两个参数都是可选的。 如果未指定任何参数,则 Get-Help 显示分配给参数的值。

PSTypeName 属性

不能在类型声明中使用扩展类型名称。 PSTypeName* 属性允许您将 参数的类型限制为扩展类型。

在此示例中, Test-Connection cmdlet 返回扩展类型。 可以使用 PSTypeName 属性将 参数的类型限制为扩展类型。

function TestType {
    param(
        [PSTypeName('Microsoft.PowerShell.Commands.TestConnectionCommand+PingMtuStatus')]
        [psobject]$MtuStatus
    )

    $MtuStatus
}

$mtu = Test-Connection -TargetName bing.com -MtuSize
TestType $mtu

System.Obsolete 属性

使用 System.Obsolete 属性标记不再受支持的参数。 如果要从函数中删除参数,但又不想中断使用该函数的现有脚本,这非常有用。

例如,假设某个函数具有 NoTypeInformation 开关参数,该参数控制类型信息是否包含在输出中。 你想要使该行为成为默认值,并从函数中删除 参数。 但是,你不希望中断使用 函数的现有脚本。 可以将 参数标记为已过时,并添加解释更改的消息。

param(
    [System.Obsolete("The NoTypeInformation parameter is obsolete.")]
    [SwitchParameter]$NoTypeInformation
)

SupportsWildcards 属性

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

param(
    [Parameter(Mandatory)]
    [SupportsWildcards()]
    [string[]]$Path
)

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

参数完成属性

ArgumentCompletions 属性

ArgumentCompletions 属性允许向特定参数添加选项卡完成值。 必须为需要选项卡补全的每个参数定义 ArgumentCompletions 属性。 ArgumentCompletions 属性类似于 ValidateSet。 这两个属性都采用一个值列表,当用户在参数名称后按 Tab 时要显示。 但是,与 ValidateSet 不同,这些值不会验证。

此属性是在 PowerShell 6.0 中引入的。

有关详细信息,请参阅 about_Functions_Argument_Completion

ArgumentCompleter 属性

ArgumentCompleter 属性允许向特定参数添加制表符完成值。 必须为需要 Tab 补全的每个参数定义 ArgumentCompleter 属性。 与 DynamicParameters 一样,当用户在参数名称后按 Tab 时,会在运行时计算可用值。

有关详细信息,请参阅 about_Functions_Argument_Completion

参数和变量验证属性

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

还可以使用验证属性来限制用户可以为变量指定的值。

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

验证属性可以应用于任何变量,而不仅仅是参数。 可以为脚本中的任何变量定义验证。

注意

将任何属性与类型化变量一起使用时,最佳做法是先声明类型前的属性。

如果在属性和变量名称之前使用换行符声明类型,该类型将被视为其自己的语句。

[string]
[ValidateLength(1,5)] $Text = 'Okay'
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

如果在类型后声明验证属性,则会在类型转换之前验证所分配的值,这可能会导致意外的验证失败。

[string] [ValidateLength(1,5)]$TicketIDFromInt        = 43
[string] [ValidateLength(1,5)]$TicketIDFromString     = '43'
[ValidateLength(1,5)] [string]$TicketIDAttributeFirst = 43
MetadataError: The attribute cannot be added because variable
TicketIDFromInt with value 43 would no longer be valid.

AllowNull 验证属性

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

param(
    [Parameter(Mandatory)]
    [AllowNull()]
    [hashtable]$ComputerInfo
)

注意

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

AllowEmptyString 验证属性

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

param(
    [Parameter(Mandatory)]
    [AllowEmptyString()]
    [string]$ComputerName
)

AllowEmptyCollection 验证属性

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

param(
    [Parameter(Mandatory)]
    [AllowEmptyCollection()]
    [string[]]$ComputerName
)

ValidateCount 验证属性

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

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

param(
    [Parameter(Mandatory)]
    [ValidateCount(1,5)]
    [string[]]$ComputerName
)

ValidateLength 验证属性

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

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

param(
    [Parameter(Mandatory)]
    [ValidateLength(1,10)]
    [string[]]$ComputerName
)

在下面的示例中,变量 $text 的值长度必须至少为一个字符,并且最多为十个字符。

[ValidateLength(1,10)] [string] $text = 'valid'

ValidatePattern 验证属性

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

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

param(
    [Parameter(Mandatory)]
    [ValidatePattern("[0-9]{4}")]
    [string[]]$ComputerName
)

在下面的示例中,变量 $ticketID 的值必须正好是一个四位数的数字,并且每个数字必须是零到九的数字。

[ValidatePattern("^[0-9]{4}$")] [string]$ticketID = 1111

ValidateRange 验证属性

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

ValidateRangeKind 枚举允许以下值:

  • - 大于零的数字。
  • - 小于零的数字。
  • NonPositive - 小于或等于零的数字。
  • NonNegative - 大于或等于零的数字。

在以下示例中, Attempts 参数的值必须介于 0 和 10 之间。

param(
    [Parameter(Mandatory)]
    [ValidateRange(0,10)]
    [Int]$Attempts
)

在以下示例中,变量 $number 的值必须介于 0 和 10 之间。

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

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

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

ValidateScript 验证属性

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

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

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

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

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

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

注意

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

重写默认错误消息

从 PowerShell 6 开始,可以使用 参数替代指定的值无效 ErrorMessage 时生成的默认错误消息。 指定 复合格式字符串。 索引 0 组件使用输入值。 索引 1 组件使用用于验证输入值的 ScriptBlock

在以下示例中, EventDate 参数的值必须大于或等于当前日期和时间。 如果该值无效,错误消息将报告指定的日期和时间太旧。

param(
    [Parameter(Mandatory)]
    [ValidateScript(
        {$_ -ge (Get-Date)},
        ErrorMessage = "{0} isn't a future date. Specify a later date."
    )]
    [DateTime]$EventDate
)

当指定的值为过去的日期时,将返回自定义错误消息。

Cannot validate argument on parameter 'EventDate'. 1/1/1999 12:00:00 AM
isn't a future date. Specify a later date.

可以使用可选的格式字符串组件在字符串中应用进一步 的格式设置。

在以下示例中, EventDate 参数的值必须大于或等于当前日期和时间。 如果该值无效,错误消息将报告指定的日期太旧。

param(
    [Parameter(Mandatory)]
    [ValidateScript(
        {$_ -ge (Get-Date).Date},
        ErrorMessage = "{0:d} isn't a future date. Specify a later date."
    )]
    [DateTime]$EventDate
)

当指定的值为过去的日期时,将返回自定义错误消息。

Cannot validate argument on parameter 'EventDate'. 1/1/1999 isn't a future
date. Specify a later date.

ValidateSet 属性

ValidateSet 属性为参数或变量指定一组有效值,并启用 Tab 自动补全。 如果参数或变量值与集中的值不匹配,PowerShell 将生成错误。 在以下示例中, Detail 参数的值只能是 Low、Average 或 High。

param(
    [Parameter(Mandatory)]
    [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"

此示例在运行时返回以下错误:

MetadataError: The attribute cannot be added because variable Message with
value bye would no longer be valid.

使用 ValidateSet 还可以启用该参数的值的 Tab 键扩展。 有关详细信息,请参阅 about_Tab_Expansion

使用类的动态 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
)

注意

IValidateSetValuesGenerator 是在 PowerShell 6.0 中引入的

ValidateNotNull 验证属性

ValidateNotNull 属性指定参数值不能为 $null。 当值为 时 $null,PowerShell 将引发异常。

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

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

param(
    [Parameter()]
    [ValidateNotNull()]
    $ID
)

ValidateNotNullOrEmpty 验证属性

ValidateNotNullOrEmpty 属性指定分配的值不能是以下任何值:

  • $null
  • 空字符串 ("")
  • 空数组 (@())

当值无效时,PowerShell 将引发异常。

param(
    [Parameter(Mandatory)]
    [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 驱动器。 对于此示例,我们将创建 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
Test-UserDrivePath -Path 'User:\A_folder_that_does_not_exist'
True

ValidateTrustedData 验证属性

已在 PowerShell 6.1.1 中添加此属性。

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

另请参阅