Juergen Schubert
Juergen Schubert

Reputation: 131

PowerShell JSON set value

Folks, I do run in PowerShell some ReST api call and do get back a

$response

page                                                content
----                                                -------
@{size=20; number=0; totalPages=1; totalElements=1} {@{id=ZGR2ZS0yLnZsYWIubG9j…

When I convert to JSON

PS C:\Users\Administrator\Documents> $response | ConvertTo-Json

{
  "page": {
    "size": 20,
    "number": 0,
    "totalPages": 1,
    "totalElements": 1
  },
  "content": [
    {
      "id": "ZGR2ZS0yLnZsYWIubG9jYWw6MzAwOTpob3N0",
      "host": "ddve-2.vlab.local",
      "port": "3009",
      "notValidBefore": "Fri Mar 29 21:32:19 PDT 2019",
      "notValidAfter": "Sat Mar 29 04:32:19 PDT 2025",
      "fingerprint": "E1BB40B0284595297071177FE02BC9C76E85CD66",
      "subjectName": "CN=ddve-2.vlab.local, O=Valued DataDomain customer, OU=Hos
t Certificate, ST=CA, C=US",
      "issuerName": "CN=ddve-2.vlab.local, OU=Root CA, O=Valued Datadomain Custo
mer, L=Santa Clara, ST=CA, C=US",
      "state": "ACCEPTED",
      "type": "HOST"
    }
  ]
}
an idividual value can be seen

PS C:\Users\Administrator\Documents> $response.content.state
ACCEPTED

But setting a new value fails

PS C:\Users\Administrator\Documents> $response.content.state = 123
InvalidOperation: The property 'state' cannot be found on this object. Verify th
at the property exists and can be set.

Upvotes: 1

Views: 1807

Answers (2)

mklement0
mklement0

Reputation: 437111

Because your content property is a (single-element) array (as evidenced by its value being enclosed in [ ... ] in the JSON representation), you must use an index to specify which element's .state property to set:

$response.content[0].state = 123

Note that an index is not required for getting the value (that is, $response.content.state works and returns "ACCEPTED", as you state), because PowerShell then applies member-access enumeration, which means that it enumerates the state property values of all elements of the array (which with a single-element array returns just the single element's value, and with a multiple-element array returns an array of values).

On setting a property value, member-access enumeration is by design not supported, although the error message could certainly be more helpful - see this answer.

Upvotes: 3

Jacob
Jacob

Reputation: 1192

Your object is a PSCustomObject and the value you're trying to change is a NoteProperty on that object, you can use Add-Member with the -Force switch to overwrite it.

$Response = @"
{
  "page": {
    "size": 20,
    "number": 0,
    "totalPages": 1,
    "totalElements": 1
  },
  "content": [
    {
      "id": "ZGR2ZS0yLnZsYWIubG9jYWw6MzAwOTpob3N0",
      "host": "ddve-2.vlab.local",
      "port": "3009",
      "notValidBefore": "Fri Mar 29 21:32:19 PDT 2019",
      "notValidAfter": "Sat Mar 29 04:32:19 PDT 2025",
      "fingerprint": "E1BB40B0284595297071177FE02BC9C76E85CD66",
      "subjectName": "CN=ddve-2.vlab.local, O=Valued DataDomain customer, OU=Hos
t Certificate, ST=CA, C=US",
      "issuerName": "CN=ddve-2.vlab.local, OU=Root CA, O=Valued Datadomain Custo
mer, L=Santa Clara, ST=CA, C=US",
      "state": "ACCEPTED",
      "type": "HOST"
    }
  ]
}
"@ | ConvertFrom-Json

$Response.Content.State
$Response.Content | Add-Member -MemberType NoteProperty -Name State -Value 123 -Force
$Response.Content.State

Output

ACCEPTED
123

Upvotes: -1

Related Questions