Reputation: 195
I have the following output from a PowerShell command and want to update the value for EmployeeID
I can filter the output with $test.identifiers | where {$_.name -like "EmployeeID" }
But if I try to update the value with
$test.identifiers | where {$_.name -like "EmployeeID" } | foreach {$_.values.value = "098324"}
How can I update this nested value?
Upvotes: 1
Views: 2296
Reputation: 437062
$_.values
contains an array (or collection) objects, which explains why you can get (read) the .value
property, but not set (write) it (see below).
If you expect the array to have just one element, simply use [0]
to access that element directly:
$test.identifiers | where {$_.name -like "EmployeeID" } | foreach {
$_.values[0].value = '098324'
}
If there are multiple elements, use
$_.values | foreach { $_.value = '098324' }
to assign to them all, or, alternatively in PSv4+,
$_.values.ForEach('value', '098324')
In PSv3+ a feature called member-access enumeration allows you to access a property on a collection and have the property values from the individual elements returned as an array.
However, that only works for getting properties, not for setting them.
When you try to set, only the collection's own properties are considered, which explains the error you saw - an array itself has no .value
property.
While this asymmetry is by design, to avoid potentially unwanted bulk modification, the error message could certainly be more helpful.
Simple reproduction of the problem:
Create an object with property one
containing a single-element array with another object, with property two
:
$obj = [pscustomobject] @{ one = , [pscustomobject] @{ two = 2 } }
The default output looks as follows:
PS> $obj
one
---
{@{two=2}}
The outer {...}
indicate an array, as in your case, and what's inside is a
hashtable-like notation that PowerShell uses to represent custom objects.
Getting the nested-inside-an-array object's two
property works as intended:
PS> $obj.two
2
Trying to set it fails:
PS> $obj.two = 2.1
The property 'two' cannot be found on this object. Verify that the property exists and can be set.
To set, use .ForEach()
, for instance:
PS> $obj.ForEach('two', 2.1); $obj
one
---
{@{two=2.1}}
Upvotes: 3
Reputation: 7
Have you tried it this way with the full object path:
$test.identifiers | where {$_.name -like "EmployeeID" } | foreach {$_.identifiers.values.value = "098324"}
Upvotes: 0