Powershell喷涂嵌套的哈希表

问题描述

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

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

理想情况下,我想喷射$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) 这导致整个哈希表作为单个参数传递,并且输出

A: System.Collections.Hashtable
B: 
C:

起作用的是...

$arguments = $data.arguments
Test @arguments

让我想到,除了一个简单的变量即适当的哈希表之外,您真的无法执行任何操作。但是,我希望有人可以验证这是真的,或者指出我还没有想到的解决方案。 实际的代码需要5个参数,并使用一些冗长的名称,因为我更喜欢使用描述性名称,因此使用splatting非常适合。只需要传递哈希表就不需要创建一个新变量,这只是一个问题,只是想知道它是否真的是唯一的选择。

解决方法

我无法声称完全理解您的尝试,但是这里有一些可能会有所帮助的解决方案。

您的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())

...但是他们没有。