Powershell and Nested JSON [duplicate] - arrays

This question already has answers here:
Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2
(2 answers)
Closed 3 years ago.
I have the following JSON
{
"method": "exec",
"params": [
{
"url": "/sys/login/user",
"data": [
{
"user": "MyUsername",
"passwd": "MyPassword"
}
]
}
],
"id": 1,
"ver": "2.0"
}
I'm trying to build this JSON using Powershell, but the output is not correct, below is my code.
$fullJson=#{}
$params=#()
$paramsdata=#()
$paramsdata+=#{"user"="mailapi"}
$paramsdata+=#{"passwd"="**********"}
$params+=#{"url"="/sys/login/user"}
$params+=#{"data"=$paramsdata}
$fullJson.Add("method", "exec")
$fullJson.Add("params",$params)
$fullJson.Add("id", "1")
$fullJson.Add("ver", "2.0")
$JsonBody=$fullJson | ConvertTo-Json
$x=Invoke-WebRequest -Uri https://10.10.10.10/jsonrpc -Body $JsonBody -Method Post
The output is the below
{
"method": "exec",
"params": [
{
"url": "/sys/login/user"
},
{
"data": "System.Collections.Hashtable System.Collections.Hashtable"
}
],
"id": "1",
"ver": "2.0"
}
The problem is DATA properties is not correct format, it should be an a nested array inside the first one, but it seems that its being added as a hashtable.
This problem is the data array should be built like this one below
"params": [
{
"url": "/sys/login/user",
"data": [
{
"user": "MyUsername",
"passwd": "MyPassword"
}
]
But with my code, its being built like this
"params": [
{
"url": "/sys/login/user"
},
{
"data": "System.Collections.Hashtable System.Collections.Hashtable"
}
],
Any help in updating this.
Thanks

Use the -Depth option in ConvertTo-Json :
Specifies how many levels of contained objects are included in the
JSON representation. The default value is 2.
Your desired depth is 4 (object -> params -> data -> username/password) :
$JsonBody=$fullJson | ConvertTo-Json -Depth 4

Related

Powershell 7.2.5 ConvertFrom-Json Outputting Array as One Object

I'm using the AWS CLI command aws iam list-users in Powershell 7.2.5 and trying to convert the output from JSON to a Powershell Object.
The JSON output of the above command looks like this (actual values omitted):
{
"Users": [
{
"Path": "/",
"UserName": "username1",
"UserId": "userid1",
"Arn": "arnid1",
"CreateDate": "createddate"
},
{
"Path": "/",
"UserName": "username2",
"UserId": "userid2",
"Arn": "arnid2",
"CreateDate": "createddate"
},
{
"Path": "/",
"UserName": "username3",
"UserId": "userid3",
"Arn": "arnid3",
"CreateDate": "createddate"
}
]
}
When I try and run the following code to create an array of Powershell Objects the output comes out as one Object.
$users = ConvertFrom-Json -InputObject $usersJson
Users
-----
{#{Path=/; UserName=username1; UserId=userid1; Arn=arnid1; CreateDate=createddate}, #{Path=/; UserName=username2; UserId=userid2; Arn=arnid2; CreateDate=createddate}, #{Path=/; UserName=username3; UserId=userid3; Arn=arnid3; CreateDate=createddate}}
Have read over countless posts and am now at a loss of what to do.
Any help would be greatly appreciated.
Santiago's comment was correct:
$users.Users shows all the entries as individual objects.

How to add a value to an existing JSON object via Powershell

I have pulled a large amount of data from a website via REST and converted it to JSON.
I have extracted the specific entry in JSON I need to edit. See below
$variables = contains all the data converted to JSON
$dacpacvariable = contains the specific entry I need to edit (which is below)
{
"Id": "c1f4fe9b-3c4d-8j02-0e7x-0a6528bn192c",
"Name": "Variable1",
"Value": "abc123",
"Description": null,
"Scope": {
"Machine": [
"Machines-1"
]
},
}
I need to edit the scope section to look like the following:
"Scope": {
"Machine": [
"Machines-1",
"Machines-2"
]
},
And then add the whole entry with the edited scope back to the larger JSON.
Any ideas?
You might simply replace the Attribute "Machine" with its new value like:
$dacpacvariable = $dacpacvariable.Scope.Machine = $dacpacvariable.Scope.Machine + "Machines-2"
Do you mean something like this:
$json = #'
{
"Id": "c1f4fe9b-3c4d-8j02-0e7x-0a6528bn192c",
"Name": "Variable1",
"Value": "abc123",
"Description": null,
"Scope": {
"Machine": [
"Machines-1"
]
}
}
'# | ConvertFrom-Json
$json.Scope.Machine += 'Machines-2'
$json | ConvertTo-Json # -Depth 99 unsure how many nestings there are in the complete json
Output:
{
"Id": "c1f4fe9b-3c4d-8j02-0e7x-0a6528bn192c",
"Name": "Variable1",
"Value": "abc123",
"Description": null,
"Scope": {
"Machine": [
"Machines-1",
"Machines-2"
]
}
}

How to add objects to a blank array in a json file using powershell

here is my json body .
{
"source": 2,
"revision": 3,
"description": null,
"triggers": [],
"releaseNameFormat": "Release-$(rev:r)",
"tags": [],
"pipelineProcess": {
"type": 1
},
"properties": {
"DefinitionCreationSource": {
"$type": "System.String",
"$value": "BuildSummary"
},
"System.EnvironmentRankLogicVersion": {
"$type": "System.String",
"$value": "2"
}
},
"id": 5,
"name": "CheckListAPI - CD",
"path": "\\Admin",
"projectReference": null,
"url": "",
"_links": {
"self": {
"href": ""
},
"web": {
"href": ""
}
}
}
I want to add some values inside the brackets at "triggers": [],
What I'm trying to get is:
"triggers":
[
{
"artifactAlias": "_DV_NJ_PIPE",
"triggerConditions": [],
"triggerType": 1
}
],
i tried -replace and replace() saving the json file to local system, but none of them are working, I even tried to edit the json file directly like this but failed.
$alias = $json.triggers
foreach ($artifact in $alias )
{
$artifact.artifactAlias = "_$DefName"
$artifact.triggerConditions = "{}"
$artifact.triggertype = "artifactSource"
}
Please help.
You can import the json file as PowerShell objects, manipulate the structure until it looks the way you want it to and export it back to json format:
$pipeline = Get-Content .\input.json | ConvertFrom-Json
$trigger = [ordered]#{
artifactAlias = "_DV_NJ_PIPE"
triggerConditions = #()
triggerType = 1
}
$pipeline.triggers += $trigger
$pipeline | ConvertTo-Json -Depth 5 | Out-File .\output.json
As it was pointed out in the comments, it is of course also possible to import the trigger definition from a json file instead of building it in a hash table.

JQ: How to turn output of array selector back into an array? [duplicate]

This question already has an answer here:
Output the results of select operation in an array - jq
(1 answer)
Closed 2 years ago.
I'm using the select function with jq to parse for items in a list that contain a certain value. I want the resulting output to be a json list, but jq gives me the objects individually:
Example:
$ a='{
"FOO": {
"name": "Donald",
"location": "Stockholm"
},
"BAR": {
"name": "Walt",
"location": "Stockholm"
},
"BAZ": {
"name": "Jack",
"location": "Whereever"
}
}'
$ echo $a | jq '.[] | select(.location=="Stockholm")'
{
"name": "Donald",
"location": "Stockholm"
}
{
"name": "Walt",
"location": "Stockholm"
}
Instead I want the output to be a json list like this:
[
{
"name": "Donald",
"location": "Stockholm"
},
{
"name": "Walt",
"location": "Stockholm"
}
]
How can I do this with jq?
In general, you can stick square brackets around any expression to gather all its outputs into an array.
[.[] | select(.location=="Stockholm")]
Sometimes it makes sense not to break up the input array in the first place, but use map to transform it:
map(select(.location=="Stockholm"))

PowerShell ConvertTo-JSON with multiple arrays

I'm trying to convert data to JSON as input for a REST API. The challenge I have is that the data should consist of multiple depths (For a lack of better words). The code I'm using now is:
(#{name = "Contoso"; all_assets = "false"; all_users="false"; rules= #{type="fqdn"; operator="match"; terms=#("contoso") } }| ConvertTo-Json)
the output now is:
{
"all_users": "false",
"name": "Contoso",
"all_assets": "false",
"rules": {
"operator": "match",
"terms": [
"contoso"
],
"type": "fqdn"
}
}
The REST-Api is complaining that the data contains invalid characters. Looking at the output, the section "rules:" contains { } instead of [ ]. I've been trying all kinds of tricks but I can't seem to figure this one out.
Anyone know what I'm doing wrong here?
If you want rules to contain an array of objects instead of an object with properties, enclose everything that goes inside the rules with #().
Because terms then becomes the 3rd level, you need to add parameter -Depth to the ConvertTo-Json cmdlet:
For better readability, I didn't do this as one-liner
#{
name = "Contoso"
all_assets = "false"
all_users = "false"
rules = #(
#{
type = "fqdn"
operator = "match"
terms = #("contoso")
}
)
} | ConvertTo-Json -Depth 3
Output:
{
"all_users": "false",
"name": "Contoso",
"all_assets": "false",
"rules": [
{
"operator": "match",
"terms": [
"contoso"
],
"type": "fqdn"
}
]
}
For what it's worth...
Not the answer to the Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2 issue, but how you might generally build a PowerShell expression from a Json file using ConvertTo-Expression cmdlet:
'{
"all_users": "false",
"name": "Contoso",
"all_assets": "false",
"rules": [
{
"operator": "match",
"terms": [
"contoso"
],
"type": "fqdn"
}
]
}' | ConvertFrom-Json | ConvertTo-Expression
[pscustomobject]#{
'all_users' = 'false'
'name' = 'Contoso'
'all_assets' = 'false'
'rules' = ,[pscustomobject]#{
'operator' = 'match'
'terms' = ,'contoso'
'type' = 'fqdn'
}
}

Resources