PowerShell 中函數是一系列 PowerShell 語句的組合。當你經過函數的名稱調用函數時,函數中的語句會被順序的執行,就像在命令行中執行它們同樣。程序員
function Say-HelloWorld
{ Write-Host "hello world!" }
定義函數必須使用 function 關鍵字,而且爲函數提供一個名稱。而後用花括號把 PowerShell 語句括起來。
調用函數的方式也很簡單,好比上面的函數連參數都沒有定義,直接寫函數名稱就能夠了:shell
> Say-HelloWorld
PowerShell 中命令的命名是很是有特點的,都是 "動詞 - 名詞" 的模式。MS 也建議咱們以一樣的模式來命名自定義的函數,以保證代碼的可讀性。
好比咱們定義的函數 Say-HelloWorld 就遵循這樣的規則。再舉個例子,好比你要定義一個把日誌信息寫到文件中的函數,那可能就要命名爲 Write-Log 之類的名稱了。數組
MS 甚至對經常使用的名稱給出了具體的規範,有興趣的同窗能夠去讀讀:Approved Verbs for Windows PowerShell Commands。函數
在 shell 世界中位置參數(Position Patameters)是廣泛存在的。其實就是在函數或腳本中咱們能夠經過默認存在的變量 $args 來引用傳遞給函數或腳本的參數。$args 變量是一個數組,因此咱們須要經過索引語法來引用具體的參數,如 $args[0],$args[1] … spa
咱們在下面的函數中引用位置參數:命令行
function Say-Hello { Write-Host("Hello {0} {1}!" -f $args[0], $args[1]) }
> Say-Hello "Nick" "Li"
除了使用位置參數,咱們還能夠在聲明函數時指定命名參數。使用命名的參數還能夠爲參數指定默認值。日誌
function Say-Hello($name, $count=3) { for(;$count -gt 0;$count--) { Write-Host("Hello {0}!" -f $name) } }
> Say-Hello "Nick" 2
做爲 C# 程序員筆者比較喜歡把參數寫在小括號裏面,可是在 PowerShell 中更常見的參數聲明方式爲使用 Param 關鍵字:code
function Say-Hello { Param ( $name, $count=3 ) for(;$count -gt 0;$count--) { Write-Host("Hello {0}!" -f $name) } }
這兩種聲明函數參數的方式是徹底等價的,因此你能夠選擇本身喜歡的方式。對象
在調用函數時,咱們還能夠經過指定參數名稱的方式爲函數傳參:blog
> Say-Hello -name "Jack" -count 5
PowerShell 中的函數能夠很輕鬆的支持從 Pipeline 輸入參數,下面是一個簡單的 demo:
function Say-Hello { Param ( [parameter(Mandatory=$true, ValueFromPipeline=$true)] $name ) process { Write-Host("Hello {0}!" -f $name) } }
在上面的函數聲明中咱們把函數的主體放入了 process 程序塊。在 process 塊中的語句會根據 Pipeline 中對象的個數執行屢次。也就是說,若是咱們經過 Pipeline 爲函數傳遞 3 個參數,那麼 process 塊中的代碼就會執行 3 次。
[parameter(Mandatory=$true, ValueFromPipeline=$true)] 說明能夠經過 Pipeline 傳遞參數 name。試一下經過 Pipeline 傳參:
> "Jack","Nick","Alice" | Say-Hello
注意,此時還能夠經過 Say-Hello "Nick" 的方式調用函數,咱們只是在基本功能的基礎上添加了對 Pipeline 的支持。
函數只存在於建立它的上下文中(scope),好比定義函數的腳本。若是想要在一個腳本中引用在另一個腳本中定義的函數,須要使用 source(.) 命令。在當前的腳本 A 中使用 source 命令並指定另一個腳本 B 做爲參數,會把 B 中定義的函數、別名和變量引入到腳本 A 的上下文中(scope)。
好比筆者在 Write-Log.ps1 文件中定義了函數 Write-Log,在另一個腳本中使用 Write-Log 的方法爲:
# 此處能夠寫絕對路徑也能夠寫相對路徑
. "./Write-Log.ps1" Write-Log -Message 'It's a test message'
函數自身會建立一個上下文(scope),在函數中定義的變量在函數外部是不可見的。
可是在函數內部卻能夠訪問在函數外部定義的變量,好比下面的 demo:
$world = "Hello world!" function Say-Hello
{ Write-Host($world) }
> Say-Hello