about_Splatting

应用到: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0

主题

about_Splatting

简短说明

介绍如何在 Windows PowerShell® 中使用展开将参数传递给命令。

详细说明

[本主题由来自密西西比州格尔夫波特的 Rohn Edwards 所著,他是一名系统管理员,也是 2012 年脚本编写大赛高级组的优胜者。已为 Windows PowerShell 3.0 进行修订。]

展开是将参数值的集合作为一个单元传递到命令的方法。Windows PowerShell 将集合中的每个值与命令参数相关联。Splatted 参数值将存储在已命名的展开变量中,这看起来类似于标准变量,但以 At 符号 (@) 开头而不是美元符号 ($)。At 符号通知 Windows PowerShell 你要传递一个值集合,而不是单个值。

展开可使你的命令更短且更易于阅读。你可以在不同的命令调用中重复使用展开值,并使用展开将参数值从 $PSBoundParameters 自动变量传递给其他脚本和函数。

从 Windows PowerShell 3.0 开始,你还可以使用展开表示命令的所有参数。

语法

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

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

若要为位置参数提供参数值(其中不需要参数名称),请使用数组语法。若要提供参数名称和值对,请使用哈希表语法。展开的值可以显示在参数列表中的任意位置。

当展开时,你无需使用哈希表或数组即可传递所有参数。你可以通过使用展开来传递某些参数,通过位置或参数名称传递其他参数。此外,你可以在单个命令中展开多个对象,因此你为每个参数传递的值不超过一个。

使用哈希表的展开

使用哈希表来展开参数名称和值对。你可以将此格式用于所有参数类型,包括位置和命名参数以及开关参数。

以下示例比较同一个目录中可将 Test.txt 文件复制到 Test2.txt 文件的两个 Copy-Item 命令。

第一个示例使用包含参数名称的传统格式。

        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 中的哈希表的语法是:@{ <name>=<value>; <name>=<value>; …}

使用数组的展开

使用数组展开位置参数的值,这些参数不需要参数名称。这些值在数组中必须以位置编号的顺序排列。

以下示例比较同一个目录中可将 Test.txt 文件复制到 Test2.txt 文件的两个 Copy-Item 命令。

第一个示例使用忽略参数名称的传统格式。参数值在命令中以位置顺序显示。

        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"}

第二个和第三个命令针对 Write-Host 命令中的展开使用 $Colors 变量。若要使用 $Colors 变量,请将美元符号 ($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."

此示例显示如何通过使用展开和 $PSBoundParameters 自动变量将其参数转发到其他命令。

$PSBoundParameters 自动变量是一个目录 (System.Collections.Generic.Dictionary),该目录包含在运行脚本或函数时使用的所有参数名称和值。

在以下示例中,我们使用 $PSBoundParameters 变量将传递给脚本或函数的参数值从 Test2 函数转发到 Test1 函数。两个从 Test2 对 Test1 函数的调用都使用展开。

              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

展开命令参数

你可以使用展开表示命令的参数。此技术在创建代理函数(即,调用其他命令的函数)时很有用。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 的所有实例,如以下示例所示。

        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