Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to parse json response in powershell

managed to get the JSON data with

$R= Invoke-WebRequest -Uri $url -Headers $headers -ContentType "application/json"   -Method Get -UseBasicParsing
$x = $R.Content | Out-String | ConvertFrom-Json 

now I've a JSON file like this :

{
  "id": 1000,
  "name_with_namespace": "myProjectName1",

},
{
  "id": 1001,
  "name_with_namespace": "myProjectName2",

},
{
  "id": 1002,
  "name_with_namespace": "myProjectName3",

}

now I need to extract all the occurence of "name_with_namespace" and "id" where "name_with_namespace" = "myProjectName.*"

How can I do it in one shot?

I've tried this:

foreach ($name in $x.name_with_namespace) {
    if ( $name -match ".*myProjectName.*" ) {    
        write-host "$name - $x.id"               
    }   
}

but I got this:

myProjectName1 1000 1001 1002
myProjectName2 1000 1001 1002
myProjectName3 1000 1001 1002

I understand that the issue is on $x.id, how can I get the right value instead of everything ?

my expected output is

myProjectName1 1000
myProjectName2 1001
myProjectName3 1002
like image 856
ClaudioM Avatar asked Mar 06 '18 16:03

ClaudioM


People also ask

How do I query JSON data in PowerShell?

One way to query an API with PowerShell and get some JSON in return is to use the Invoke-WebRequest cmdlet. This cmdlet can query any web service/site over HTTP and return information (not just JSON). In this example, you're using it as an example to get some JSON to work with.

How do I filter JSON data in PowerShell?

First, we need to load the JSON from our file. To do this we use the Get-Content cmdlet and tell it that we want to load the JSON from our file created above. After that we use the pipe operator | to, well, pipe the result into our next cmdlet which is called ConvertFrom-Json .

How do I convert JSON data to CSV in PowerShell?

To convert the JSON file to the CSV file using PowerShell, we need to use the ConvertTo-CSV command as a pipeline. For example, we have a JSON file called PatchingServer. JSON stored at C:\temp and its content is as below.


2 Answers

You're drilling down a level too far when you define your loop. Just iterate $x and then check against the specific property inside the loop.

foreach ($name in $x) {
    if ( $name.name_with_namespace -match ".*myProjectName.*" ) {    
        write-host "$($name.name_with_namespace) - $($name.id)"               
    }   
}

Edit: On a side note, you can simplify your -match to just "myProjectName" and it will work just as well, and probably faster.

like image 142
TheMadTechnician Avatar answered Sep 19 '22 08:09

TheMadTechnician


ConvertFrom-Json has some odd behavior with pipelines. The issue is that ConvertFrom-Json wraps the JSON array in an array and then passes the whole array down the pipeline as one item. This is fine in most cases, but if the outermost level is a JSON array, then that whole array gets passed as a single object into the pipeline.

Compare:

PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object  {": $_"}
: 1 2 3

PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object  {": $_"}
: 1
: 2
: 3

PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object  {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object  {": $_"}
: 1 2 3

Note with that last example we can duplicate the problem with the unary comma operator.

The issue has been reported here for PowerShell Core 6.

Try this code:

$j = @'
[
    {
        "id": 1000,
        "name_with_namespace": "myProjectName1"
    },
    {
        "id": 1001,
        "name_with_namespace": "myProjectName2"
    },
    {
        "id": 1002,
        "name_with_namespace": "myProjectName3"
    }
]
'@

($j | Out-String | ConvertFrom-Json) |
Where-Object name_with_namespace -match ".*myProjectName.*" |
ForEach-Object {
    "$($_.name_with_namespace) $($_.id)"
}
like image 45
Bacon Bits Avatar answered Sep 20 '22 08:09

Bacon Bits