Search code examples
jsonpowershellpowershell-3.0

Reading a json file in key value pair in the same order that's given in input


I am writing a PowerShell Script, which will read a json file having different sections, like job1, job2 and so on.. Now my objective is to read each section separately and to loop through it as a key value pair. I also need to maintain the order of the input file, because the jobs are scheduled in sequence. and these jobs run taking the values from the json file as input.

I tried using Powershell version 5.1, in which I created PSCustomObject but the order is getting sorted alphabetically, which I DON'T want.


Json File :

{ "Job1": [
        {
    "Ram"                                   : "India",
    "Anthony"                               : "London",
    "Elena"                                 : "Zurich"
    }],

    "Job2": [
            { 
    "Build"                                : "fail",
    "Anthony"                              : "right",
    "Sam"                                  : "left"

    }]}

$json = Get-Content -Path C:\PowershellScripts\config_File.json | 
ConvertFrom-Json

$obj = $json.Job1

$json.Job1 | Get-Member -MemberType NoteProperty | ForEach-Object {

$key = $_.Name
$values  = [PSCustomObject][ordered]@{Key = $key; Value = $obj."$key"}
$values
}

I am expecting to loop through each section separately and in the same order that's provided in the json file. For example looping through Job1 section and to fetch only the Values in the same order that's in the json file.


Solution

  • I will guarantee that this is not the best way to do this, but it works.

    $json = Get-Content -Path C:\PowershellScripts\config_File.json | 
        ConvertFrom-Json
    $out = ($json.Job1 | Format-List | Out-String).Trim() -replace "\s+(?=:)|(?<=:)\s+"
    $out -split "\r?\n" | ForEach-Object {
        [PSCustomObject]@{Key = $_.Split(":")[0]; Value = $_.Split(":")[1]}
    }
    

    Explanation:

    The JSON object is first output using Format-List to produce the Property : Value format, which is piped to Out-String to make that output a single string. Trim() is used to remove surrounding white space.

    The -replace removes all white space before and after : characters.

    The -split \r?\n splits the single string into an array of lines. Each of those lines is then split by the : character (.Split(":")). The [0] index selects the string on the left side of the :. The [1] selects the string on the right side of the :.