Jacob
Jacob

Reputation: 1192

Splatting the -property parameter in Select-Object or Format-Table

Is there any way to splat the -property parameter of Select-Object or Format-Table.

Take for example the following, I was hoping to create a hash table of custom expressions as opposed to @{N="Address"; E={$ping[0].Address}} but I have been unsuccesful.

Is there another approach to achieve this (or similar)?

Desired Outcome

$param = @{
    'Property' = @{
        'Address' = $ping[0].Address
        'IPV4 Address' = $ping[0].IPV4Address.IPAddressToString
        'IPV6 Address' = $ping[0].IPV6Address.IPAddressToString
        'Count' = $_.Count
        'Average' = [Math]::Round($_.Average)
        'Maximum' = $_.Maximum
        'Minimum' = $_.Minimum
    }

}

$ping | Measure-Object -Property ResponseTime -Average -Minimum -Maximum | Select-Object @param
$ping | Measure-Object -Property ResponseTime -Average -Minimum -Maximum | Format-Table @param

Errors

Select-Object : The IPV6 Address key is not valid.
At line:15 char:76
+ ... operty ResponseTime -Average -Minimum -Maximum | Select-Object @param
+                                                      ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Select-Object], NotSupport 
   edException
    + FullyQualifiedErrorId : DictionaryKeyIllegal,Microsoft.PowerShell.Comman 
   ds.SelectObjectCommand

Format-Table : The IPV6 Address key is not valid.
At line:16 char:76
+ ... roperty ResponseTime -Average -Minimum -Maximum | Format-Table @param
+                                                       ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Format-Table], NotSupporte 
   dException
    + FullyQualifiedErrorId : DictionaryKeyIllegal,Microsoft.PowerShell.Comman 
   ds.FormatTableCommand

   ds.SelectObjectCommand

Below is how I would normally create custom properties, but with larger objects it becomes unwieldly and more difficult to manage.

$ping | Measure-Object -Property ResponseTime -Average -Minimum -Maximum | Format-Table -Property `
    @{N="Address";E={$ping[0].Address}},
    @{N="IPV4 Address";E={$ping[0].IPV4Address.IPAddressToString}},
    @{N="IPV6 Address";E={$ping[0].IPV6Address.IPAddressToString}},
    @{N="Count";E={$_.Count}},
    @{N="Average";E={[Math]::Round($_.Average)}},
    @{N="Maximum";E={$_.Maximum}},
    @{N="Minimum";E={$_.Minimum}}

Desired output

Address      IPV4 Address  IPV6 Address             Count Average Maximum Minimum
-------      ------------  ------------             ----- ------- ------- -------
Google.co.uk 216.58.206.67 2a00:1450:4009:814::2003    10      12      13      12

Upvotes: 1

Views: 3568

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200293

The syntax for a calculated property is

@{
    Name = 'Foo'
    Expression = { ... }
}

or

@{
    Label = 'Foo'
    Expression = { ... }
}

which define the name/label of one such property, as well as how it's calculated. The scriptblock (an anonymous function) defers the execution of the expression, so that the property value is not calculated before the hashtable is used with Format-Table (or Select-Object, etc.).

The argument to the parameter -Property is an array of these hashtables. Even if you're splatting the parameters you still need to define that list of hashtables.

Your code is mapping the parameter name to a single hashtable with the names and expressions you want to use for the calculated properties. That is invalid syntax, though. And even if the syntax was valid you'd still not get the desired result, because the calculation of the values is not deferred (because they're not defined in scriptblocks).

To get the result you want you'd need to define $param like so:

$param = @{
    Property = @{N="Address";E={$ping[0].Address}},
               @{N="IPV4 Address";E={$ping[0].IPV4Address.IPAddressToString}},
               @{N="IPV6 Address";E={$ping[0].IPV6Address.IPAddressToString}},
               @{N="Count";E={$_.Count}},
               @{N="Average";E={[Math]::Round($_.Average)}},
               @{N="Maximum";E={$_.Maximum}},
               @{N="Minimum";E={$_.Minimum}}
}

However, unless you want to splat that same parameter definition multiple times I fail to see the advantage of the above over defining the calculated properties directly in the Format-Table or Select-Object statement.

Upvotes: 6

Related Questions