about_Splatting
簡短描述
描述如何使用曲線將參數傳遞至 PowerShell 中的命令。
詳細描述
Splatting 是將參數值集合當做單位傳遞至命令的方法。 PowerShell 會將集合中的每個值與命令參數產生關聯。 Splatted 參數值會儲存在具名的splatting變數中,其看起來像標準變數,但以 At 符號 (@
) 開頭,而不是貨幣符號 ($
)。 At 符號會告知 PowerShell 您傳遞值的集合,而不是單一值。
展開可讓您的命令更短且更容易閱讀。 您可以在不同的命令呼叫中重複使用展開值,並使用splatting將參數值從 $PSBoundParameters
自動變數傳遞至其他腳本和函式。
從 Windows PowerShell 3.0 開始,您也可以使用曲線來代表命令的所有參數。
語法
<CommandName> <optional parameters> @<HashTable> <optional parameters>
<CommandName> <optional parameters> @<Array> <optional parameters>
若要提供位置參數的參數值,其中不需要參數名稱,請使用數位語法。 若要提供參數名稱和值組,請使用哈希表語法。 Splatted 值可以出現在參數清單中的任何位置。
展開時,您不需要使用哈希表或數位來傳遞所有參數。 您可以使用曲線傳遞某些參數,並依位置或參數名稱傳遞其他參數。 此外,您可以在單一命令中分割多個物件,因此不會針對每個參數傳遞多個值。
從 PowerShell 7.1 開始,您可以藉由在命令中明確定義參數來覆寫 Splatted 參數。
使用哈希表展開
使用哈希表來 Splat 參數名稱和值組。 您可以將此格式用於所有參數類型,包括位置參數和參數參數。 位置參數必須依名稱指派。
下列範例會比較將Test.txt檔案複製到相同目錄中Test2.txt檔案的兩 Copy-Item
個命令。
第一個範例會使用包含參數名稱的傳統格式。
Copy-Item -Path "test.txt" -Destination "test2.txt" -WhatIf
第二個範例使用哈希表展開。 第一個命令會建立參數名稱與參數值組的哈希表,並將它儲存在變數中 $HashArguments
。 第二個命令會使用 $HashArguments
命令中的變數進行展開。 At 符號 (@HashArguments
) 會取代 命令中的貨幣符號 ($HashArguments
)。
若要提供 WhatIf 參數的值,請使用 $True
或 $False
。
$HashArguments = @{
Path = "test.txt"
Destination = "test2.txt"
WhatIf = $true
}
Copy-Item @HashArguments
注意
在第一個命令中,At 符號 (@
) 表示哈希表,而不是 Splatted 值。 PowerShell 中哈希表的語法如下: @{<name>=<value>; <name>=<value>; ...}
使用陣列展開
使用陣列來分割位置參數的值,而不需要參數名稱。 這些值必須在陣列中以位置編號順序排列。
下列範例會比較將Test.txt檔案複製到相同目錄中Test2.txt檔案的兩 Copy-Item
個命令。
第一個範例會使用省略參數名稱的傳統格式。 參數值會依命令的位置順序顯示。
Copy-Item "test.txt" "test2.txt" -WhatIf
第二個範例使用陣列展開。 第一個命令會建立參數值的陣列,並將其儲存在變數中 $ArrayArguments
。 這些值會依陣列中的位置順序排列。 第二個命令會在 $ArrayArguments
展開的命令中使用 變數。 At 符號 (@ArrayArguments
) 會取代 命令中的貨幣符號 ($ArrayArguments
)。
$ArrayArguments = "test.txt", "test2.txt"
Copy-Item @ArrayArguments -WhatIf
使用 ArgumentList 參數
數個 Cmdlet 都有 ArgumentList 參數,可用來將參數值傳遞至 Cmdlet 所執行的腳本區塊。 ArgumentList 參數會採用傳遞至腳本區塊的值陣列。 PowerShell 有效地使用數位展開將值系結至腳本區塊的參數。 使用 ArgumentList 時,如果您需要將數位當做系結至單一參數的單一對象傳遞,則必須將數位包裝為另一個數位的唯一元素。
下列範例有一個腳本區塊,其接受單一參數是字串陣列。
$array = 'Hello', 'World!'
Invoke-Command -ScriptBlock {
param([string[]]$words) $words -join ' '
} -ArgumentList $array
在此範例中,只有中的 $array
第一個專案會傳遞至腳本區塊。
Hello
$array = 'Hello', 'World!'
Invoke-Command -ScriptBlock {
param([string[]]$words) $words -join ' '
} -ArgumentList (,$array)
在此範例中, $array
會包裝在陣列中,讓整個陣列以單一物件的形式傳遞至腳本區塊。
Hello World!
範例
範例 1:在不同的命令中重複使用 Splatted 參數
此範例示範如何在不同的命令中重複使用 Splatted 值。 此範例中的命令會使用 Write-Host
Cmdlet 將訊息寫入主機程式控制台。 它會使用旋轉來指定前景和背景色彩。
若要變更所有命令的色彩,只要變更變數的值 $Colors
即可。
第一個命令會建立參數名稱和值的哈希表,並將哈希表儲存在變數中 $Colors
。
$Colors = @{ForegroundColor = "black"; BackgroundColor = "white"}
第二個和第三個Write-Host
命令會使用 $Colors
變數在命令中展開。 若要使用 $Colors variable
,請將貨幣符號 ($Colors
) 取代為 At 符號 (@Colors
)。
#Write a message with the colors in $Colors
Write-Host "This is a test." @Colors
#Write second message with same colors. The position of splatted
#hash table does not matter.
Write-Host @Colors "This is another test."
範例 2:使用 $PSBoundParameters 轉送參數
這個範例示範如何使用曲線和 $PSBoundParameters
自動變數,將其參數轉送至其他命令。
自動 $PSBoundParameters
變數是字典物件 (System.Collections.Generic.Dictionary),其中包含腳本或函式執行時所使用的所有參數名稱和值。
在下列範例中 $PSBoundParameters
,我們會使用 變數,將傳遞至腳本或函式的參數值從 Test2
函式轉送至 函 Test1
式。 這兩個對函式Test2
的Test1
呼叫都會使用展開。
function Test1
{
param($a, $b, $c)
"a = $a"
"b = $b"
"c = $c"
}
function Test2
{
param($a, $b, $c)
#Call the Test1 function with $a, $b, and $c.
Test1 @PSBoundParameters
#Call the Test1 function with $b and $c, but not with $a
Test1 -b $PSBoundParameters.b -c $PSBoundParameters.c
}
Test2 -a 1 -b 2 -c 3
a = 1
b = 2
c = 3
a =
b = 2
c = 3
範例 3:使用明確定義的參數覆寫 Splatted 參數
此範例示範如何使用明確定義的參數覆寫 Splatted 參數。 當您不想建置新的哈希表或變更您用來 Splat 之哈希表中的值時,這會很有用。
變數 $commonParams
會儲存參數,以在位置中 East US
建立虛擬機。 變數 $allVms
是要建立的虛擬機清單。 我們會逐一查看清單,並使用 $commonParams
來分割參數來建立每個虛擬機。 不過,我們想要 myVM2
在其他虛擬機不同的區域中建立。 您可以明確定義中的 Location 參數,以取代 中的$commonParams
索引鍵值Location
,而不是調整$commonParams
哈希表。 New-AzVm
$commonParams = @{
ResourceGroupName = "myResourceGroup"
Location = "East US"
VirtualNetworkName = "myVnet"
SubnetName = "mySubnet"
SecurityGroupName = "myNetworkSecurityGroup"
PublicIpAddressName = "myPublicIpAddress"
}
$allVms = @('myVM1','myVM2','myVM3',)
foreach ($vm in $allVms)
{
if ($vm -eq 'myVM2')
{
New-AzVm @commonParams -Name $vm -Location "West US"
}
else
{
New-AzVm @commonParams -Name $vm
}
}
範例 4:在單一命令中使用多個 Splatted 物件
您可以在單一命令中使用多個 Splatted 物件。 在此範例中,不同的參數會在不同的哈希表中定義。 哈希表會在單 Write-Host
一命令中展開。
$a = @{
Message = 'Hello', 'World!'
}
$b = @{
Separator = '|'
}
$c = @{
BackgroundColor = 'Cyan'
ForegroundColor = 'Black'
}
Write-Host @a @b @c
Splatting 命令參數
您可以使用曲線來代表命令的參數。 當您建立 Proxy 函式,也就是呼叫另一個命令的函式時,這項技術很有用。 這項功能是在 Windows PowerShell 3.0 中引進的。
若要將命令的參數展開,請使用 @Args
來表示命令參數。 這項技術比列舉命令參數更容易,即使所呼叫命令的參數變更,它仍可運作,而不會進行修訂。
此功能會 $Args
使用自動變數,其中包含所有未指派的參數值。
例如,下列函式會呼叫 Get-Process
Cmdlet。 在此函式中, @Args
表示 Cmdlet 的所有參數 Get-Process
。
function Get-MyProcess { Get-Process @Args }
當您使用 函 Get-MyProcess
式時,所有未指派的參數和參數值都會傳遞至 @Args
,如下列命令所示。
Get-MyProcess -Name PowerShell
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
463 46 225484 237196 719 15.86 3228 powershell
Get-MyProcess -Name PowerShell_Ise -FileVersionInfo
ProductVersion FileVersion FileName
-------------- ----------- --------
6.2.9200.16384 6.2.9200.1638... C:\Windows\system32\WindowsPowerShell\...
您可以在 @Args
具有明確宣告參數的函式中使用。 您可以在函式中多次使用它,但您輸入的所有參數都會傳遞至 的所有 實例 @Args
,如下列範例所示。
function Get-MyCommand
{
Param ([switch]$P, [switch]$C)
if ($P) { Get-Process @Args }
if ($C) { Get-Command @Args }
}
Get-MyCommand -P -C -Name PowerShell
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
50 112.76 78.52 16.64 6880 1 powershell
Path : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Extension : .exe
Definition : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Source : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Version : 10.0.22621.3085
Visibility : Public
OutputType : {System.String}
Name : powershell.exe
CommandType : Application
ModuleName :
Module :
RemotingCapability : PowerShell
Parameters :
ParameterSets :
HelpUri :
FileVersionInfo : File: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
InternalName: POWERSHELL
OriginalFilename: PowerShell.EXE.MUI
FileVersion: 10.0.22621.1 (WinBuild.160101.0800)
FileDescription: Windows PowerShell
Product: Microsoft® Windows® Operating System
ProductVersion: 10.0.22621.1
Debug: False
Patched: False
PreRelease: False
PrivateBuild: False
SpecialBuild: False
Language: English (United States)
備註
如果您使用 CmdletBinding 或 Parameter 屬性將函式設為進階函式,則$args
函式中不再提供自動變數。 進階函式需要明確的參數定義。
PowerShell Desired 狀態設定 (DSC) 並非設計來使用噴灑。 您無法使用 Splatting 將值傳遞至 DSC 資源。 如需詳細資訊,請參閱 Gael Colas 一文 虛擬 Splatting DSC 資源。