关于 Splatting

简短说明

介绍如何使用 Splatting 将参数传递给 PowerShell 中的命令。

详细说明

[本主题由密西西比州格尔夫波特的 Rohn Edwards 提供,他是一名系统管理员,也是 2012 年脚本游戏高级组的获胜者。 针对 Windows PowerShell 3.0 进行了修订。

展开是一种将参数值集合作为 unit 传递给命令的方法。 PowerShell 将集合中的每个值与命令参数相关联。 散列传递的参数值存储在命名的散列传递变量中,这些变量看起来和标准变量相似,但以 At 符号 (@) 而不是美元符号 ($) 开头。 At 符号告知 PowerShell 你正在传递值集合,而不是单个值。

通过使用 Splatting,可以使命令变得更简洁、更易读。 您可以在不同的命令调用中重复使用展开值,并使用展开将参数值从 $PSBoundParameters automatic 变量传递到其他脚本和函数。

从 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

$HashArguments = @{
  Path = "test.txt"
  Destination = "test2.txt"
  WhatIf = $true
}
Copy-Item @HashArguments

注: 在第一个命令中,At 符号 (@) 表示哈希表,而不是展开值。 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

例子

此示例说明如何在不同的命令中重用展开的值。 此示例中的命令使用 Write-Host cmdlet 将消息写入主机程序控制台。 它使用喷洒来指定前景和背景色。

若要更改所有命令的颜色,只需更改 $Colors 变量的值。

第一个命令创建参数名称和值的哈希表,并将哈希表存储在 $Colors 变量中。

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

第二个和第三个命令使用了 $Colors 变量,以便在 Write-Host 命令中进行散列传递。 若要使用 $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."

此示例说明如何使用展开和 $PSBoundParameters automatic 变量将其参数转发到其他命令。

$PSBoundParameters 自动变量是一个字典对象(System.Collections.Generic.Dictionary),其中包含运行脚本或函数时使用的所有参数名称和值。

在以下示例中,我们使用 $PSBoundParameters 变量将传递给脚本或函数的参数值从 Test2 函数转发到 Test1 函数。 从 Test1Test2 函数进行的两次调用都使用散列传递。

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
}
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,如以下命令所示。

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
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.e
Extension          : .exe
Definition         : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.e
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.14393.0 (rs1_release.160715-1616
                     FileDescription:  Windows PowerShell
                     Product:          Microsoft Windows Operating System
                     ProductVersion:   10.0.14393.0
                     Debug:            False
                     Patched:          False
                     PreRelease:       False
                     PrivateBuild:     False
                     SpecialBuild:     False
                     Language:         English (United States)

笔记

PowerShell Desired State Configuration (DSC) 未设计为使用散列传递。 不能使用散列传递将值传入 DSC 资源。 有关详细信息,请参阅 Gael Colas 的文章 Pseudo-Splatting DSC 资源

另请参阅

about_Arrays

about_Automatic_Variables

about_Hash_Tables

关于_参数