Reputation: 31
How to filter a PowerShell object that contains a square bracket column name?
for example:
$data | select-object DisplayName, ``[Custom.Class`].Name
would return:
DisplayName | [Custom.Class].Name |
---|---|
Cat | Animal |
Toyota | Car |
daisy | Plant |
Honda | Car |
If i wanted to filter $data to list only [Custom.Class].Name = Car
How can I filter it?
I tried
$data | Where-Object {$_.``[Custom.Class`].Name -eq 'Car'}
but it returned an error
Missing property name after reference operator.
Tried
$data | Where-Object {$_."[Custom.Class].Name" -eq 'Car'}
but returned nothing
I am expecting to list only the filtered data on the column with a bracket name
Upvotes: 3
Views: 145
Reputation: 439932
You're seeing a bug in Select-Object
, reported a while back in GitHub issue #17068:
In property names (possibly positionally implied -Property
arguments) that contain wildcard metacharacters meant to be interpreted verbatim - notably [
and ]
- attempting to escape them with `
mistakenly causes the `
chars. to be retained as part of the resulting property name.
That is, ``[Custom.Class``].Name
(which is the same as '`[Custom.Class`].Name'
) tries to select a property named verbatim `[Custom.Class`].Name
from the input objects, and in their absence reports $null
values.
Note that the form in the question, ``[Custom.Class`].Name
(which is the same as '`[Custom.Class].Name'
) is still a wildcard expression due to the effectively unescaped ]
, albeit a broken one, and therefore matches none of the input properties and is simply omitted from the output objects.
Incidentally, the same applies to the -Property
and -MemberName
parameters of Where-Object
and ForEach-Object
, respectively, when using simplified syntax.
As a workaround, replace:
... | select-object DisplayName, ``[Custom.Class``].Name
with:
... | select-object DisplayName,
@{ Name = '[Custom.Class].Name';
Expression = { $_.'[Custom.Class].Name' } }
That is, use a calculated property to select the property whose name contains wildcard metacharacters, in which case the property names are not subject to interpretation as wildcard expressions.
(By contrast, Expression = '[Custom.Class].Name'
, i.e. specifying just the property name as a string, would again be subject to wildcard interpretation.)
Then your 2nd attempt to query the property named [Custom.Class].Name
verbatim will work (though you may want to use '...'
instead of "..."
to enclose the property name, given that string interpolation isn't needed):
$data | Where-Object { $_."[Custom.Class].Name" -eq 'Car'}
Upvotes: 4