I have a function that returns a complex nested hash table data structure, where part of it forms the arguments for a further function call, and part of it is strings for reporting errors that result in the arguments not being populated. Ideally I would like to splat just the arguments hash table, but I am starting to think that can't be done. So, an example of the basic problem looks like this...
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'
}
Ideally I want to splat $data.arguments
, so something like this...
Test @data.arguments
But that doesn't work, resulting in the error
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'.
So I tried...
Test @(data.arguments)
Which results in the error
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.
I also tried...
Test @($data.arguments)
Which results in the whole hash table being passed as a single argument and the output is
A: System.Collections.Hashtable
B:
C:
What DOES work is...
$arguments = $data.arguments
Test @arguments
Which has me thinking you really cannot splat anything but a simple variable that is an appropriate hash table. But, I am hoping someone can verify that is indeed true, or point out the solution I haven't come up with yet. The actual code requires 5 arguments, with somewhat verbose names because I prefer descriptive names, so splatting is very much an appropriate solution. Needing to make a new variable with just the hash table to be passed isn't an issue, just wondering if it really is the only option.
That's not possible.
Any variable (and only variables) provided with "@" instead of "$" for a function parameter is declared as TokenKind "SplattedVariable".
PS: Some quick tests from my side which could have succeed (apart from PS design):
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())
... but they didn't.