函式
函式(function)把一段會重複用到的邏輯包起來、取個名字,需要時直接呼叫。寫得好的 PowerShell 函式用起來就像內建 cmdlet:有參數、可以補全、能放進管線。本頁介紹寫出實用函式所需的最少知識。
最簡單的函式
函式命名請沿用「動詞-名詞」慣例(見 探索指令),使用核准的動詞,別人才能憑直覺猜到用法。
參數
參數寫在 param() 區塊裡:
function Get-Greeting {
param(
[string]$Name = 'World',
[int]$Times = 1
)
1..$Times | ForEach-Object { "Hello, $Name!" }
}
Get-Greeting # Hello, World!
Get-Greeting -Name Victor -Times 2 # 輸出兩行
PowerShell 呼叫函式時,參數以 -名稱 值 傳入,不是用括號與逗號。Get-Greeting('Victor', 2) 是常見的錯誤寫法,它會把 'Victor', 2 當成一個陣列傳給第一個參數。
必填參數與驗證
用 [Parameter()] 與驗證屬性,可以在函式一開始就擋掉不合法的輸入,錯誤訊息也由 PowerShell 自動產生:
function Set-Level {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name,
[ValidateSet('Low', 'Medium', 'High')]
[string]$Level = 'Medium',
[ValidateRange(1, 100)]
[int]$Count = 1
)
"$Name 等級 $Level,數量 $Count"
}
Mandatory:沒給這個參數,PowerShell 會提示使用者輸入。ValidateSet:值只能是指定的幾個,而且在終端機裡可以用 Tab 補全這些選項。ValidateRange:數值必須在範圍內。[CmdletBinding()]:讓函式具備進階函式的能力,例如自動支援-Verbose、-ErrorAction等通用參數。建議每個正式的函式都加上。
輸出:小心「所有東西都會輸出」
PowerShell 函式不需要 return。函式內任何沒有被接住的運算式結果,都會變成函式的輸出:
function Test-Output {
$list = [System.Collections.ArrayList]::new()
$list.Add('a') # Add 會回傳索引 0,這個 0 也會混進輸出!
'done'
}
Test-Output # 輸出 0 和 done,而不是只有 done
避免的方法是把不要的輸出丟掉:[void]$list.Add('a'),或 $null = $list.Add('a'),或 $list.Add('a') | Out-Null。
return 的作用是「輸出這個值並立即結束函式」,不是唯一的輸出方式。要在螢幕上顯示訊息又不污染輸出,用 Write-Verbose 或 Write-Host。
管線輸入
讓函式能接收管線傳來的物件,需要宣告 ValueFromPipeline,並把處理邏輯寫在 process 區塊:
function Get-FileSize {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[System.IO.FileInfo]$File
)
process {
[pscustomobject]@{
Name = $File.Name
KB = [math]::Round($File.Length / 1KB, 1)
}
}
}
Get-ChildItem *.log | Get-FileSize
process 區塊會針對管線中的每一個物件執行一次,所以這個函式能處理任意多個檔案。
說明文件
在函式最上面加上註解式說明,Get-Help 就能像查 cmdlet 一樣查你的函式:
function Get-Greeting {
<#
.SYNOPSIS
產生問候語。
.PARAMETER Name
要問候的對象。
.EXAMPLE
Get-Greeting -Name Victor
#>
param([string]$Name = 'World')
"Hello, $Name!"
}
Get-Help Get-Greeting -Examples
相關資料
- about_Functions(官方說明)
- 進階函式與模組的影片教學見 腳本與模組
- 下一步:錯誤處理