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)

切換參數很容易使用,而且偏好使用布林參數,其具有較不自然的 PowerShell 語法。

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

-IncludeAll

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

-IncludeAll $true

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

參數設計考慮

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

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

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

  • 參數不應為必要參數。 唯一需要讓 switch 參數成為必要參數時,才需要區分參數集。

  • 您可以透過 -MySwitch:$boolValue 和 ,透過 明確設定布林值的參數,並使用 進行 splatting $params = @{ MySwitch = $boolValue }

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

    if ($MySwitch) { ... }

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

動態參數

動態參數是 Cmdlet、函式或腳本的參數,這些參數僅適用于特定條件。

例如,數個提供者 Cmdlet 的參數只有在提供者磁片磁碟機中使用 Cmdlet 時,或提供者磁片磁碟機的特定路徑才可使用。 例如,只有在檔案系統磁片磁碟機中使用,才能在 、 Get-ContentSet-Content Cmdlet 上使用 Add-Content Encoding 參數。

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

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

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

語法如下所示:

dynamicparam {<statement-list>}

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

下列範例顯示名為 NamePath的標準參數,以及名為 KeyCount的選擇性動態參數。 KeyCount參數位於 ByRegistryPath 參數集中,且類型 Int32 為 。 只有在Path參數的值以 開頭 HKLM: 時,才能在函式中使用 Get-SampleKeyCount參數,表示它正在使用登錄磁片磁碟機中 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 參數。 它會使用值為0Position 引數。 因此,從 命令省略時 -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 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 屬性的參數宣告。

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

實驗性屬性

使用實驗性屬性將某些程式碼宣告為 實驗 性。 如需屬性的完整描述,請參閱 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
)

注意

如果類型轉換器設定為字串,則 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 的值長度必須至少為一個字元,且最多 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列舉允許下列值:

  • 數 - 大於零的數位。
  • 數 - 小於零的數位。
  • 非Positive - 小於或等於零的數位。
  • 非負 數 - 大於或等於零的數位。

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

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

在下列範例中,變數 $number 的值必須介於零到十之間。

[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屬性會指定參數或變數的有效值集,並啟用索引標籤完成。 如果參數或變數值不符合集合中的值,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 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 本身會在內部使用 屬性,而且不適用於外部使用。

另請參閱