about_Functions_Advanced_Parameters

簡短描述

說明如何將參數新增至進階函式。

詳細描述

您可以將參數新增至您撰寫的進階函式,並使用參數屬性和自變數來限制函式使用者以 參數提交的參數值。

除了 PowerShell 自動新增至所有 Cmdlet 和進階函式的通用參數之外,您新增至函式的參數也可供使用者使用。 如需 PowerShell 一般參數的詳細資訊,請參閱 about_CommonParameters

從 PowerShell 3.0 開始,您可以使用 splatting 搭配 @Args 來表示命令中的參數。 在簡單和進階的函式上,噴灑有效。 如需詳細資訊,請參閱 about_Functionsabout_Splatting

參數值的型別轉換

當您提供字串做為預期不同類型之參數的自變數時,PowerShell 會隱含地將字串轉換成參數目標類型。 進階函式會執行參數值的文化特性不變剖析。

相較之下,區分文化特性的轉換會在編譯 Cmdlet 的參數係結期間執行。

在此範例中,我們會建立採用 參數的 [datetime] Cmdlet 和腳本函式。 目前的文化特性會變更為使用德文設定。 德文格式的日期會傳遞至 參數。

# 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 或 false 值,因此當 switch 參數存在時,其值為 true 且不存在時,其值為 false

例如,的 Recurse 參數 Get-ChildItem 是 switch 參數。

若要在函式中建立 switch 參數,請在 switch 參數定義中指定類型。

例如,您的函式可能會有選項可將資料輸出為位元組數組:

param([switch]$AsByteArray)

參數很容易使用,而且偏好使用布爾參數,其語法較不自然的PowerShell。

例如,若要使用 switch 參數,使用者會在 命令中輸入 參數。

-IncludeAll

若要使用布爾參數,使用者輸入 參數和布爾值。

-IncludeAll $true

建立參數參數時,請仔細選擇參數名稱。 請確定參數名稱會將參數的效果傳達給使用者。 避免模棱兩可的字詞,例如 可能表示需要值的篩選最大值

參數設計考慮

  • 參數不應該被指定為預設值。 它們應該一律預設為 false。

  • 參數預設會從位置參數中排除。 即使其他參數是隱含位置,參數也不會。 您可以在 Parameter 屬性中覆寫該屬性,但會混淆使用者。

  • 應該設計 Switch 參數,使其將命令從其預設行為移至較不常見或更複雜的模式。 命令最簡單的行為應該是不需要使用參數的預設行為。

  • 參數不應該是必要參數。 唯一需要進行參數強制參數的情況,就是需要區分參數集。

  • 從布爾值明確設定參數可以透過 -MySwitch:$boolValue 和 來展開 $params = @{ MySwitch = $boolValue }

  • Switch 參數的類型為 SwitchParameter,其會隱含轉換成布爾值。 參數變數可以直接在條件表達式中使用。 例如:

    if ($MySwitch) { ... }

    不需要寫入 if ($MySwitch.IsPresent) { ... }

動態參數

動態參數是 Cmdlet、函式或腳本的參數,只能在特定條件下使用。

例如,數個提供者 Cmdlet 具有只有在提供者磁碟驅動器中使用 Cmdlet 或提供者磁碟驅動器特定路徑時,才可用的參數。 例如,只有在文件系統磁碟驅動器中使用 、、 和 Set-Content Cmdlet 時,才能使用 Add-ContentGet-ContentEncoding 參數。

您也可以建立只有在函式命令中使用另一個參數或另一個參數具有特定值時,才會顯示的參數。

動態參數很有用,但只有在需要時才使用這些參數,因為它們可能很難讓使用者探索。 若要尋找動態參數,用戶必須位於提供者路徑中、使用 Cmdlet 的 Get-Command ArgumentList 參數,或使用Get-HelpPath 參數。

若要建立函式或腳本的動態參數,請使用 DynamicParam 關鍵詞。

語法如下所示:

dynamicparam {<statement-list>}

在語句清單中,使用 if 語句來指定函式中可用參數的條件。

下列範例顯示名為 Name 和 Path 的標準參數,以及名為 KeyCount 的選擇性動態參數。 KeyCount 參數位於ByRegistryPath參數集中,且類型為 Int32只有在Path參數的值以 開頭HKLM:時,才能在函式中使用 Get-Sample KeyCount參數,指出它正用於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。 如需詳細資訊,請參閱 PositionalBinding about_Functions_CmdletBindingAttribute

自變數的值 Position 會指定為整數。 位置值 0 代表命令中的第一個位置,位置值 1 代表命令中的第二個位置,依序顯示。

如果函式沒有位置參數,PowerShell 會根據宣告參數的順序,將位置指派給每個參數。 不過,最佳做法是不要依賴此指派。 當您想要參數為位置時,請使用 Position 自變數。

下列範例會 宣告 ComputerName 參數。 它會使用 Position 值為 0自變數。 因此,從 命令省略時 -ComputerName ,其值必須是命令中第一個或只有未命名的參數值。

param(
    [Parameter(Position=0)]
    [string[]]$ComputerName
)

ParameterSetName 自變數

ParameterSetName 變數會指定參數所屬於的參數集。 如果未指定任何參數集,參數會屬於函式所定義的所有參數集。 若要是唯一的,每個參數集必須至少有一個參數不是任何其他參數集的成員。

注意

對於 Cmdlet 或函式,有 32 個參數集的限制。

下列範例會在參數集中宣告 ComputerName 參數Computer、參數集中的 UserName 參數User,以及這兩個參數集中的 Summary 參數。

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

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

    [Parameter()]
    [switch]$Summary
)

每個自變數中只能指定一個ParameterSetName值,而且每個Parameter屬性中只能指定一個ParameterSetName自變數。 若要在多個參數集中包含參數,請新增其他 Parameter 屬性。

下列範例會明確將 Summary 參數新增ComputerUser 參數集。 Summary 參數在參數集合中是選擇性的Computer,在參數集合中User為必要參數。

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 Valueby 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 屬性會建立參數的替代名稱。 您可以指派給參數的別名數目沒有限制。

下列範例顯示將 CN 和 MachineName 別名新增至強制 ComputerName 參數的參數宣告。

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

認證屬性

Credential 屬性是用來指出參數接受認證。 下列範例顯示使用 Credential 屬性的參數宣告。

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

實驗屬性

使用 Experimental 屬性將某些程式代碼宣告為實驗性。 如需屬性的完整描述,請參閱 about_Experimental_Features

PSDefaultValue 屬性

PSDefaultValue 會在腳本中指定命令參數的預設值。 Cmdlet 會顯示 Get-Help 此資訊。 若要查看預設值資訊,函式必須包含以批注為基礎的說明。 例如:

<#
    .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 屬性有兩個自變數:

  • 說明 - 描述預設值的字串。 Cmdlet 會顯示 Get-Help 此資訊。
  • Value - 參數的預設值。

這兩個自變數都是選擇性的。 如果您未指定任何自變數,則 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 屬性可讓您將索引標籤完成值新增至特定參數。 必須針對需要 Tab 自動完成的每個參數定義 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
)

注意

如果類型轉換器設定為字串,因為字串類型不接受Null值,則AllowNull屬性無法運作。 您可以針對此案例使用 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 的值長度必須至少為一個字元,且最多 10 個字元。

[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 - 小於或等於零的數位。
  • 非負數 - 大於或等於零的數位。

在下列範例中,Attempts 參數的值必須介於零到 10 之間。

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

在下列範例中,變數 $number 的值必須介於零到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 也會啟用該參數值的索引標籤展開。 如需詳細資訊,請參閱 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 管理員 istration (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 本身會在內部使用 屬性,不適用於外部使用。

另請參閱