Powershell 生成嵌套哈希 table

Powershell splatting a nested hash table

我有一个函数 returns 一个复杂的嵌套散列 table 数据结构,其中一部分构成进一步函数调用的参数,一部分是用于报告错误的字符串导致参数未被填充。 理想情况下,我只想将参数散列 table 展开,但我开始认为这是不可能的。 因此,基本问题的示例如下所示...

function Test {
    param (
        [String]$A,
        [String]$B,
        [String]$C
    )
    Write-Host "A: $A"
    Write-Host "B: $B"
    Write-Host "C: $C"
}

$data = @{
    arguments = @{
        A = 'A string'
        B = 'Another string'
        C = 'The last string'
    }
    kruft = 'A string that doesn not need to get passed'
}

理想情况下我想要 splat $data.arguments,所以像这样... Test @data.arguments 但这不起作用,导致错误

The splatting operator '@' cannot be used to reference variables in an expression. '@data' can be used only as an argument to a command. To 
reference variables in an expression use '$data'.

所以我尝试了... Test @(data.arguments) 导致错误

data.arguments : The term 'data.arguments' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is correct and try again.

我也试过了... Test @($data.arguments) 这导致整个散列 table 作为单个参数传递,输出为

A: System.Collections.Hashtable
B: 
C:

有效的是...

$arguments = $data.arguments
Test @arguments

这让我觉得除了一个简单的变量是一个合适的散列 table,你真的不能拼写任何东西。但是,我希望有人可以验证这确实是真的,或者指出我还没有想出的解决方案。 实际代码需要 5 个参数,名称有些冗长,因为我更喜欢描述性名称,所以拼写是一个非常合适的解决方案。需要创建一个仅包含要传递的散列 table 的新变量不是问题,只是想知道它是否真的是唯一的选择。

我不能声称完全理解您的尝试,但这里有一些可能有用的解决方案。

您的 Test 函数需要三个字符串,但我在您的示例中没有看到任何满足该条件的字符串。我要么将其更改为接受 Hashtable (这是有问题的数据类型),要么让它接受字符串数组并传递 $data.arguments.values

使用 Hashtable:

function Test {
  param (
    [Hashtable]$hash
  )

  write-host $hash.A
  write-host $hash.B
  write-host $hash.C
}

Test $data.arguments

使用 String 数组:

function Test {
  param (
    [String[]]$a
  )

  $a | % { write-host $_ }
}

Test $data.arguments.values

这不可能。

为函数参数提供“@”而不是“$”的任何变量(且仅是变量)被声明为 TokenKind“SplattedVariable”。

参见: https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.language.tokenkind?view=powershellsdk-7.0.0

PS: 我这边的一些快速测试可能会成功(除了 PS 设计):

Write-Host 'Test 1' -ForegroundColor Yellow
Test @$data.arguments

Write-Host 'Test 2' -ForegroundColor Yellow
Test @$($bla = $data.arguments)

Write-Host 'Test 3' -ForegroundColor Yellow
Test @$bla = $data.arguments

Write-Host 'Test 4' -ForegroundColor Yellow
Test @$bla = $data.arguments.GetEnumerator()

Write-Host 'Test 5' -ForegroundColor Yellow
Test @$($data.arguments.GetEnumerator())

...但他们没有。