about_Script_Blocks
簡短描述
定義腳本區塊是什麼,並說明如何在PowerShell程式設計語言中使用腳本區塊。
詳細描述
在PowerShell程式設計語言中,腳本區塊是語句或表達式的集合,可用來做為單一單位。 語句的集合可以括在大括弧中,{}
定義為函式,或儲存在腳本檔案中。 腳本區塊可以傳回值,並接受參數和自變數。
語法上,腳本區塊是大括弧中的語句清單,如下列語法所示:
{<statement list>}
腳本區塊會傳回腳本區塊中所有命令的輸出,可以是單一對象或陣列。
您也可以使用 return
關鍵詞來指定傳回值。 關鍵詞 return
不會影響或隱藏從腳本區塊傳回的其他輸出。 不過, return
關鍵詞會在該行結束腳本區塊。 如需詳細資訊,請參閱 about_Return。
如同函式,腳本區塊可以包含參數。 使用 Param 關鍵詞來指派具名參數,如下列語法所示:
{
Param([type]$Parameter1 [,[type]$Parameter2])
<statement list>
}
注意
在腳本區塊中,與函式不同,您無法在大括弧之外指定參數。
如同函式,腳本區塊可以包含 DynamicParam
、 Begin
、 Process
和 End
關鍵詞。 如需詳細資訊,請參閱 about_Functions 和 about_Functions_Advanced。
使用腳本區塊
腳本區塊是 Microsoft .NET Framework 類型的 System.Management.Automation.ScriptBlock
實例。 命令可以有腳本區塊參數值。 例如, Invoke-Command
Cmdlet 具有 ScriptBlock
採用腳本區塊值的參數,如下列範例所示:
Invoke-Command -ScriptBlock { Get-Process }
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
999 28 39100 45020 262 15.88 1844 communicator
721 28 32696 36536 222 20.84 4028 explorer
...
Invoke-Command
也可以執行具有參數區塊的腳本區塊。
參數是使用 ArgumentList 參數來指派位置。
Invoke-Command -ScriptBlock { param($p1, $p2)
"p1: $p1"
"p2: $p2"
} -ArgumentList "First", "Second"
p1: First
p2: Second
此範例中的文稿區塊會使用 param
關鍵字來建立參數 $p1
和 $p2
。 字串 “First” 系結至第一個參數 ($p1
) 和 “Second” 系結至 ($p2
)。
如需 ArgumentList 行為的詳細資訊,請參閱about_Splatting。
您可以使用變數來儲存和執行文稿區塊。 下列範例會將文稿區塊儲存在變數中,並將它傳遞至 Invoke-Command
。
$a = { Get-Service BITS }
Invoke-Command -ScriptBlock $a
Status Name DisplayName
------ ---- -----------
Running BITS Background Intelligent Transfer Ser...
呼叫運算子是另一種執行儲存在變數中的腳本區塊的方式。
如同 Invoke-Command
,呼叫運算子會在子範圍中執行腳本區塊。 呼叫運算子可讓您更輕鬆地搭配腳本區塊使用參數。
$a ={ param($p1, $p2)
"p1: $p1"
"p2: $p2"
}
&$a -p2 "First" -p1 "Second"
p1: Second
p2: First
您可以使用指派,將腳本區塊的輸出儲存在變數中。
PS> $a = { 1 + 1}
PS> $b = &$a
PS> $b
2
PS> $a = { 1 + 1}
PS> $b = Invoke-Command $a
PS> $b
2
如需呼叫運算子的詳細資訊,請參閱 about_Operators。
搭配參數使用延遲系結腳本區塊
接受管線輸入的具型別參數,可讓您在 參數上使用延遲系結 腳本區塊。 您可以使用延遲系結腳本區塊做為速記來定義管線 Cmdlet 的參數,再執行它。
在延遲系結腳本區塊中,您可以使用管線變數 $_
來參考 物件中的管道。
# Both examples rename config.log to old_config.log
# Without delay-binding
dir config.log | ForEach-Object -Process {
Rename-Item -Path $_ -NewName "old_$($_.Name)"
}
# With delay-binding
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
在更複雜的 Cmdlet 中,延遲系結腳本區塊允許重複使用物件中的一個管道填入其他參數。
延遲系結腳本區塊做為參數的注意事項:
您必須明確指定與延遲系結腳本區塊搭配使用的任何參數名稱。
參數不得為不具型別,而且參數的類型不能是
[scriptblock]
或[object]
。如果您使用延遲系結腳本區塊而不提供管線輸入,您會收到錯誤。
Rename-Item -NewName {$_.Name + ".old"}
Rename-Item : Cannot evaluate parameter 'NewName' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input. At line:1 char:23 + Rename-Item -NewName {$_.Name + ".old"} + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [Rename-Item], ParameterBindingException + FullyQualifiedErrorId : ScriptBlockArgumentNoInput, Microsoft.PowerShell.Commands.RenameItemCommand