How to retrieve JSON data using PowerShell? - json

I have this JSON. Trying to retrieve tactics array by using below code in PowerShell.
Why the actual output is weird even though tactics contains comma separated values, it is considering as one value with space separated values.
How to get the expected output?
My JSON:
{
"displayName": "travel with mailbox permission",
"tactics": [
"InitialAccess",
"PrivilegeEscalation"
],
"techniques": [
"T1078",
"T1548"
]
}
My code:
param (
[Parameter(Mandatory = $true)]
# The resourceVariable which holds the resource details
[string] $jsonvariable
)
$json = Get-AutomationVariable -Name $jsonvariable
$jsonObject = ConvertFrom-Json -InputObject $json
echo $jsonObject.tactics
Output:
Expected o/p:
InitialAccess,PrivilegeEscalation
Actual O/p :
InitialAccess PrivilegeEscalation

Try using
$json.tactics -join ','
Powershell is outputting each value in the array separately, rather than as a comma-separated list.

Related

PowerShell ConvertFrom-Json not converting JSON List to Json Object [duplicate]

This question already has answers here:
PowerShell JSON set value
(2 answers)
Closed 1 year ago.
I have a json output as list, I wanted to add a property in tags parameter using PowerShell
$json = #'
[
{
"tags": [],
"name": "[concat(parameters('factoryName'), '/Veh_Obj')]",
"properties": {
"type": "AzureDataLakeStoreFile",
}
}
]
'#
#$json = 'C:\workspace\cucumber_report.29776.json'
$obj = $json | ConvertFrom-Json
# Append new objects to the array.
$obj.tags += [pscustomobject] #{ name = 'newname1' }
# Convert back to JSON.
$obj | ConvertTo-Json -Depth 10 | Set-Content $json
But i am getting error as below
The property 'tags' cannot be found on this object. Verify that the property exists and can be set.
looks like issue is occurs only when I am passing JSON list, with normal json input this is working fine
The trailing comma in line "type": "AzureDataLakeStoreFile", leads to an error ConvertFrom-Json : Invalid JSON primitive.
$obj.GetType().Name returns Object[] (note that the most top element of the original json is an array []).
Use
$obj[0].tags += [pscustomobject] #{ name = 'newname1' }

Inputting JSON data in Powershell

Currently, I'm attempting to call upon an API to run a POST, with JSON data as the body. So I was wondering if anyone would be able to tell me how I need to format the text below inside the variable $postParams. I'm pretty new at working with JSON so I'm having so trouble with this.
Currently, I only have the following and don't know what to do about the second line on.
$postParams = #{name='Example'}
Here's is the entire data I was hoping to add to $postParams. So if you could help me with the 2nd, 4th, and 8th that'd be awesome. Thanks!
{
"name":"Example",
"template":{"name":"Template"},
"url":"http://localhost",
"page":{"name":"Landing Page"},
"smtp":{"name":"Sending Profile"},
"launch_date":"2019-10-08T17:20:00+00:00",
"send_by_date":null,
"groups":[{"name":"test group"}]
}
You'll need a here-string and ConvertFrom-Json.
here-string:
Quotation marks are also used to create a here-string. A here-string is a single-quoted or double-quoted string in which quotation marks are interpreted literally. A here-string can span multiple lines. All the lines in a here-string are interpreted as strings, even though they are not enclosed in quotation marks.
The resulting code:
# Use a PowerShell here string to take JSON as it is
$jsonString = #"
{
"name":"Example",
"template":{"name":"Template"},
"url":"http://localhost",
"page":{"name":"Landing Page"},
"smtp":{"name":"Sending Profile"},
"launch_date":"2019-10-08T17:20:00+00:00",
"send_by_date":null,
"groups":[{"name":"test group"}]
}
"#
# Pipe the string to create a new JSON object
$jsonObject = $jsonString | ConvertFrom-Json
# The resulting JSON object has properties matching the properties in the orig. JSON
$jsonObject.name
$jsonObject.url
# Nested property
$jsonObject.template.name
# Nested property in array
$jsonObject.groups[0].name
I've posted an online version of the above code at tio.run, so you can play around with it.
If you want to update several properties of the $jsonObject you can do the following:
$jsonObject.name = "NEW NAME"
$jsonObject.url = "NEW URL"
$jsonObject | ConvertTo-Json
ConvertTo-Json will take your object and create an appropriate JSON string:
{
"name": "NEW NAME",
"template": {
"name": "Template"
},
"url": "NEW URL",
"page": {
"name": "Landing Page"
},
"smtp": {
"name": "Sending Profile"
},
"launch_date": "2019-10-08T17:20:00+00:00",
"send_by_date": null,
"groups": [
{
"name": "test group"
}
]
}
If you $jsonObject has more than two levels of depth, use the -Depth parameter, otherwise not all object information will be included in the JSON string.
ConvertTo-Json:
-Depth
Specifies how many levels of contained objects are included in the JSON representation. The default value is 2.
Here is a tio.run link to a ConvertTo-Json example.
Hope that helps.
I can't test it currently, but try this.
$postParams = #'
{
"name":"Example",
"template":{"name":"Template"},
"url":"http://localhost",
"page":{"name":"Landing Page"},
"smtp":{"name":"Sending Profile"},
"launch_date":"2019-10-08T17:20:00+00:00",
"send_by_date":null,
"groups":[{"name":"test group"}]
}
'#
Make a hashtable, then convert to JSON:
$Hashtable = #{
Key1 = "Value1"
Key2 = "Value2"
}
$Json = $Hashtable | ConvertTo-Json

Looping through converted json data in Powershell that don't have key/value pairs, but rather lists of values instead?

JSON:
[
{
"Category-1": [
"Value1"
]
},
{
"Category-2": [
"Value1"
]
},
{
"Category-3": [
"Value1",
"Value2"
]
}
]
PowerShell Script:
$jsonToParse = (Get-Content -Path $jsonPath) -join "`n" | ConvertFrom-Json
foreach ($entry in $jsonToParse) {
log -Message ($entry) #Log function spits output to file
}
Output:
[10:39:03]#{Category-1=System.Object[]}
[10:39:03]#{Category-2=System.Object[]}
[10:39:03]#{Category-3-Med=System.Object[]}
How can I parse this? I have square brackets mixed with curly brackets, and I'm having a hard time finding a foothold with which to really get at the data.
What can I do to get the "Category" names? What can I do to get the "Values" for each category name? The fact that these aren't all key/value pairs is what's causing me trouble, I think.
I think what you are after is something like this:
# use the -Raw switch to get the file content as one single string
$jsonToParse = Get-Content -Path $jsonPath -Raw | ConvertFrom-Json
foreach ($entry in $jsonToParse) {
# format a string for the log file using the object ($entry) Name followed by the Value
# This Value can be an array of more than one items, so join these with a comma
$msg = '{0} = {1}' -f $entry.PSObject.Properties.Name, ($entry.PSObject.Properties.Value -join ', ')
log -Message $msg #Log function spits output to file
}
output:
[10:39:03]Category-1 = Value1
[10:39:03]Category-2 = Value1
[10:39:03]Category-3 = Value1, Value2
You have an array which contains values ("Category-1" etc). The values contain arrays with values ("Value1" etc).
$jsonToParse[0] = Category-1
$jsonToParse[1] = Category-2
$jsonToParse[2] = Category-3
$jsonToParse[1].'Category-2' = Value1
If you fill in the above examples, the output is like this!

PowerShell json duplicate keys, condense values to single array

Is there a best practice for handling JSON documents with duplicated keys in PowerShell?
Ideally would like to compile the values of said keys into a single array mapped to the key.
For example:
{
"column01" : "id1",
"column02" : "id2",
"column03: : "id3",
"column03" : "id4"
}
Transformed to:
{
"column01" : "id1",
"column02" : "id2",
"column03: : [
"id3",
"id4"
]
}
I have been exploring options with the ConvertTo-Json cmdlet, but have not found a solution.
Appreciate the help!
While JSON does allow duplicate keys, this is not recommended and I suggest handling this by normalizing the JSON. Otherwise you can certainly pass your JSON with the duplicate key to ConvertFrom-Json but this won't result in your desired output.
It should be...
$obj = #"
{ "column01" : "id1",
"column02" : "id2",
"column03" : ["id3", "id4"]
}
"#
Then using $json = $obj | ConvertFrom-Json to convert into a powershell obj.
Then you can do the same with a PowerShell object and convert to JSON.
$obj = #{
"column01" = "id1";
"column02" = "id2";
"column03" = ("id3", "id4")
}
$json = $obj | ConvertTo-Json
$json
If you want to know how to normalize the data, I suggest you either edit your question or ask a new one.

How to remove object from array in power shell?

I am trying to remove the complete object from the array not a member of the object.I am not able to find the way to remove the object there are so many solutions available to remove the item.
Can someone please suggest a way remove the complete object.
JSON Data: JSON data stored in the file.
{
"data": [
{
"id": "Caption",
"firstname": "Caption",
"lastname": "test",
"email": "test",
"requester": "test",
"password": "test",
"incNumber": "test"
}
]
}
Code : I have written the following code to read the object from the array and store into variables to do the task.Once the task is completed I want to remove the object from the array.
$file = Get-Content '\path\to\file' -Raw | ConvertFrom-Json
$file.data | % {if($_.id -eq 'Caption'){
$1 = $_.id
Write-Host $1
###Here I want to remove the whole object related to the id
}}
I think the answer in the comments is what you are looking for: file.data = $file.data | ? id -ne 'Caption'.
To give a little explanation to this, it uses ? which is actually an alias (alternative name) for the Where-Object cmdlet, which is what you use when you want to filter a collection based on some criteria (very similar to the WHERE statement in SQL if you are familiar).
The above answer is a short version, you might alternatively see this:
$file = Get-Content '\path\to\file' -Raw | ConvertFrom-Json
$Result = $file.data | Where-Object {$_.id -ne 'Caption'}
Which is passing a ScriptBlock { } to the Where-Object cmdlet and using $_ to represent each item in the pipeline, then using -ne as the not equals comparison operator to see if the ID property of that object does not match the string Caption. If that is evaluated as true, then it allows the item to pass through the pipeline, which in the above example means it ends up in the $Result variable. If the statement evaluates as false, then it discards that item in the collection and moves on to the next.