about_Splatting

適用於: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0

主題

about_Splatting

簡短描述

說明如何在 Windows PowerShell® 中使用展開 (splatting) 功能,將參數傳遞至命令。

詳細描述

[本主題是由美國密西西比州格爾夫波特市的 Rohn Edwards 投稿,他擔任系統管理員,並且是「2012 年指令碼大賽高級組」(Advanced Division of the 2012 Scripting Games) 的優勝者。已針對 Windows PowerShell 3.0 進行修訂。]

「展開」是將參數值集合以單位形式傳遞至命令的一種方法。Windows PowerShell 會將集合中的每個值與命令參數產生關聯。展開的參數值會儲存在具名的展開變數中,看起來像標準變數,但是以 At 符號 (@) 開頭,而不是貨幣符號 ($)。At 符號會讓 Windows PowerShell 知道您傳遞的是值集合,而非單一值。

展開可讓您的命令縮短,也較容易閱讀。您可以在不同的命令呼叫中重複使用展開值,並可利用展開,將 $PSBoundParameters 自動變數的參數值傳遞至其他指令碼和函式。

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

語法

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

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

若要為位置參數提供參數值 (其中不要求參數名稱),請使用陣列語法。若要提供參數名稱和值組,請使用雜湊表語法。展開的值可能會出現在參數清單中的任何位置。

展開時,不需要使用雜湊表或陣列來傳遞所有參數。您可以使用展開來傳遞某些參數,並依位置或參數名稱來傳遞其他參數。此外,您也可以在單一命令中展開多個物件,這樣針對每個參數,就只需要傳遞一個值。

使用雜湊表展開

使用雜湊表來展開參數名稱和值組。您可以將此格式用於所有參數類型,包括位置參數和具名參數,以及切換參數。

下列範例會比較兩個 Copy-Item 命令,將 Test.txt 檔複製到相同目錄中的 Test2.txt 檔。

第一個範例使用傳統格式,其中包含參數名稱。

        Copy-Item -Path "test.txt" -Destination "test2.txt" -WhatIf

第二個範例使用雜湊表展開。第一個命令會建立參數名稱與參數值組的雜湊表,並將其儲存在 $HashArguments 變數中。第二個命令會搭配展開,在命令中使用 $HashArguments 變數。在該命令中,At 符號 (@HashArguments) 會取代錢幣符號 ($HashArguments)。

若要為 WhatIf 切換參數提供值,請使用 $True 或 $False。

       PS C:\>$HashArguments = @{ Path = "test.txt"; Destination = "test2.txt"; WhatIf = $true }
       PS C:\>Copy-Item @HashArguments

注意:在第一個命令中,At 符號 (@) 是指雜湊表,而不是展開的值。Windows PowerShell 中的雜湊表語法為:@{ <名稱>=<值>; <名稱>=<值>; …}

使用陣列展開

使用陣列來展開位置參數的值,這不要求參數名稱。這些值必須依照陣列中的位置編號排序。

下列範例會比較兩個 Copy-Item 命令,將 Test.txt 檔複製到相同目錄中的 Test2.txt 檔。

第一個範例使用傳統格式,其中省略參數名稱。參數值會依照命令中的位置順序出現。

        Copy-Item "test.txt" "test2.txt" -WhatIf

第二個範例會使用陣列展開。第一個命令會建立參數值的陣列,並將其儲存在 $ArrayArguments 變數中。這些值會依照陣列中的位置順序排列。第二個命令會在展開的命令中使用 $ArrayArguments 變數。在該命令中,At 符號 (@ArrayArguments) 會取代錢幣符號 ($ArrayArguments)。

        PS C:\>$ArrayArguments = "test.txt", "test2.txt"
        PS C:\>Copy-Item @ArrayArguments -WhatIf

範例

這個範例示範如何在不同命令中,重複使用展開的值。此範例中的命令會使用 Write-Host cmdlet,將訊息寫入主機程式主控台。它會使用展開來指定前景和背景色彩。

若要變更所有命令的色彩,只要變更 $Colors 變數的值即可。

第一個命令會建立參數名稱和值的雜湊表,並將雜湊表儲存在 $Colors 變數中。

               $Colors = @{ForegroundColor = "black"
                           BackgroundColor = "white"}

第二個和第三個命令會使用 $Colors 變數,以在 Write-Host 命令中展開。若要使用 $Colors 變數,請以 At 符號 (@Colors) 取代錢幣符號 ($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."

這個範例示範如何使用展開和 $PSBoundParameters 自動變數,將其參數轉送至其他命令。

$PSBoundParameters 自動變數是字典 (System.Collections.Generic.Dictionary),其中包含在執行指令碼或函式時,所使用的所有參數名稱和值。

在下列範例中,我們使用 $PSBoundParameters 變數,將傳遞至指令碼或函式的參數值,從 Test2 函式轉送至 Test1 函式。對 Test1 函式的呼叫和來自 Test2 函式的呼叫,都使用展開。

              function Test1
              {
                   param($a, $b, $c)

                   $a
                   $b
                   $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
                   $LimitedParameters = $PSBoundParameters
                   $LimitedParameters.Remove("a") | Out-Null
                   Test1 @LimitedParameters
               }

               PS C:\> Test2 -a 1 -b 2 -c 3
               1
               2
               3
               2
               3

展開命令參數

您可以使用展開來代表命令的參數。當您在建立 Proxy 函式 (也就是呼叫另一個命令的函式) 時,這項技術會很有用。此功能是在 Windows PowerShell 3.0 中引進。

若要展開命令的參數,請使用 @Args 代表命令參數。這項技術比列舉命令參數更簡單,而且即使所呼叫之命令的參數已變更,也不需要修訂,即可運作。

此功能使用 $Args 自動變數,其中包含所有未指派的參數值。請在這裡插入區段主體。

例如,下列函式會呼叫 Get-Process cmdlet。在這個函式中,@Args 代表 Get-Process cmdlet 的所有參數。

        function Get-MyProcess { Get-Process @Args }

當您使用 Get-MyProcess 函式時,所有未指派的參數和參數值都會傳遞至 @Args,如下列命令所示。

        PS C:\> 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


        PS C:\> Get-MyProcess -Name PowerShell_Ise -FileVersionInfo 

        ProductVersion   FileVersion      FileName
        --------------   -----------      --------
        6.2.9200.16384   6.2.9200.1638... C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe

您可以在已明確宣告參數的函式中使用 @Args。您可以在單一函式中多次使用 @Args,但是您輸入的所有參數都會傳遞至 @Args 的所有執行個體,如下列範例所示。

        function Get-MyCommand 
        { 
            Param ([switch]$P, [switch]$C)
            if ($P) { Get-Process @Args }
            if ($C) { Get-Command @Args }
        }        

        PS C:\> Get-MyCommand -P -C -Name PowerShell

        Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
        -------  ------    -----      ----- -----   ------     -- -----------
            408      28    75568      83176   620     1.33   1692 powershell

        Path               : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
        Extension          : .exe
        Definition         : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
        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

另請參閱

about_Arrays

about_Automatic_Variables

about_Hash_Tables

about_Parameters