1

I have the following output from a PowerShell command and want to update the value for EmployeeID Unfiltered output

I can filter the output with $test.identifiers | where {$_.name -like "EmployeeID" } Filtered output

But if I try to update the value with

$test.identifiers | where {$_.name -like "EmployeeID" } | foreach {$_.values.value = "098324"} 

I get an error Error

How can I update this nested value?

6
  • 1
    ... | foreach {$_.name = "098324"} Commented Aug 23, 2018 at 17:24
  • looks what you are looking for is in a hashtable… I constructed a small hashtable to illustrate how to get the data: $x=@{id='1';value='123';isObfuscated="False"} ; $x['value'] ; $x['id'] Commented Aug 23, 2018 at 17:27
  • @iRon That changes the name and not the value Commented Aug 23, 2018 at 17:50
  • @Tom Getting the data is not the problem $test.identifiers.values.value gives me this. But updating the values is what I'm trying to do Commented Aug 23, 2018 at 17:52
  • does it work if you treat as a hashtable like this $test.identifiers.values['value']="098324" Commented Aug 23, 2018 at 19:02

2 Answers 2

3

$_.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}}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! for your very extensive answer! $test.identifiers | where {$_.name -like "EmployeeID" } | foreach {$_.values.ForEach('value', '098324')} did the trick
0

Have you tried it this way with the full object path:

$test.identifiers | where {$_.name -like "EmployeeID" } | foreach {$_.identifiers.values.value = "098324"}

2 Comments

I did, but no joy. Gives the error: The property 'value' cannot be found on this object. Verify that the property exists and can be set.
$_ in the foreach (ForEach-Object) script block represents the element of input collection $test.identifiers currently being enumerated, so using $_.identifiers is incorrect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.