共用方式為


about_Splatting

簡短描述

描述如何使用 Splatting 將參數傳遞至 PowerShell 中的命令。

完整描述

展開是將參數值集合傳遞至命令做為單位的方法。 PowerShell 會將集合中的每個值與命令參數產生關聯。 Splatted 參數值會儲存在具名 splatting 變數中,其看起來像標準變數,但以 At 符號開頭 (@) ,而不是貨幣符號 ($) 。 At 符號會告知 PowerShell 您正在傳遞值集合,而不是單一值。

展開可讓您的命令更短且更容易閱讀。 您可以在不同的命令呼叫中重複使用展開值,並使用splatting將參數值從 $PSBoundParameters 自動變數傳遞至其他腳本和函式。

從 Windows PowerShell 3.0 開始,您也可以使用曲線來代表命令的所有參數。

Syntax

<CommandName> <optional parameters> @<HashTable> <optional parameters>
<CommandName> <optional parameters> @<Array> <optional parameters>

若要提供位置參數的參數值,其中不需要參數名稱,請使用數位語法。 若要提供參數名稱和值組,請使用哈希表語法。 Splatted 值可以出現在參數清單中的任何位置。

展開時,您不需要使用哈希表或數位來傳遞所有參數。 您可以使用展開傳遞某些參數,並依位置或參數名稱傳遞其他參數。 此外,您可以在單一命令中擷取多個物件,因此不會針對每個參數傳遞一個以上的值。

從 PowerShell 7.1 開始,您可以藉由在命令中明確定義參數來覆寫 Splatted 參數。

使用哈希表進行展開

使用哈希表來擷取參數名稱和值組。 您可以針對所有參數類型使用此格式,包括位置參數和參數。 位置參數必須依名稱指派。

下列範例會比較將 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 函式。 這兩個呼叫函 Test1 式都會 Test2 使用展開。

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 參數。 當您不想在哈希表中建立新的哈希表或變更您用來展開的哈希表中的值時,這會很有用。

變數 $commonParams 會儲存參數,以在位置中 East US 建立虛擬機。 變數 $allVms 是要建立的虛擬機清單。 我們會迴圈查看清單,並使用 $commonParams 將參數展開以建立每部虛擬機。 不過,我們想要 myVM2 在其他虛擬機不同的區域中建立。 您可以明確定義 中的 New-AzVmLocation 參數,以取代 中的$commonParams索引鍵值Location,而不是調整$commonParams哈希表。

$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

展開命令參數

您可以使用曲線來表示命令的參數。 當您建立 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&reg; Windows&reg; Operating System
                     ProductVersion:   10.0.22621.1
                     Debug:            False
                     Patched:          False
                     PreRelease:       False
                     PrivateBuild:     False
                     SpecialBuild:     False
                     Language:         English (United States)

備註

如果您使用 CmdletBindingParameter 屬性將函式設為進階函式,則 $args 函式中不再提供自動變數。 進階函式需要明確的參數定義。

PowerShell Desired State Configuration (DSC) 並非設計來使用曲線。 您無法使用展開將值傳遞至 DSC 資源。 如需詳細資訊,請參閱 Gael Colas 文章 虛擬 Splatting DSC 資源

另請參閱