skip to Main Content

I’m new to JSON construction and I can’t quite wrap my brain round how I do this. I can’t even think of the vocabulary to ask Google…

I want to create JSON that looks like this:

[{
   "common": {
     "attributes": {
       "logtype": "accesslogs",
       "service": "login-service",
       "hostname": "login.example.com"
     }
   },
   "logs": [{
       "message": "User 'xyz' logged in"
     },{
       "message": "User 'xyz' logged out",
       "attributes": {
         "auditId": 123
       }
     }]
}]

Note the whole lot is in a single array element, inside a single hashtable element containing "common" and "logs". Common contains a single hashtable "attributes" element with hashtable key pairs. Logs contains a sub array, consisting of a single array element, with hashtable inside. The hashtable can have an optional attributes sub hashtable with key pairs.

Common appears once, logs array elements can repeat.

I hope that makes sense. Help greatly appreciated.

Thanks.

I’ve tried lots, and I can’t get close.

3

Answers


  1. Chosen as BEST ANSWER

    I brute forced it in the end. There's some very fiddly syntax to get certain records to render the object in just the right way so as to force the correct JSON output. To get the entire output in square brackets I had to do this:

    $null = $arr_Body.Add(@($hsh_Body))
    

    Here's the sample code that did it in the end:

    ## Build the common record
    $hsh_CommonRecord = [ordered]@{
        "timestamp"=98765;
        "message"="random message";
    }
    $hsh_CommonAttributes = @{
        "logType" = "accesslogs";
        "service" = "login-service";
        "hostname" = "login.example.com";
    }
    $hsh_CommonRecord += @{"attributes"=$hsh_CommonAttributes;}
    
    ## Build the logs records
    $hsh_LogAttributes = @{
        "About"="i'm a hsh_LogAttribute";
        "AuditID"="abc123";
    }
    
    $hsh_LogRecord = [ordered]@{
        "timestamp"=123456;
        "message"="random message";
    }
    $hsh_LogRecord += @{"attributes"=$hsh_LogAttributes;}
    $arr_Logs = [System.Collections.ArrayList]@($hsh_LogRecord)
    $arr_Logs += @($hsh_LogRecord) # add more log records here
    
    $hsh_Body = @{"common"=$hsh_CommonRecord}
    $hsh_Body += @{"logs"=$arr_Logs}
    
    $arr_Body = [System.Collections.ArrayList]@()
    $null = $arr_Body.Add(@($hsh_Body))
    $arr_Body | ConvertTo-Json -Depth 10
    

  2. If you mean you are looking to construct the equivalent objects in PowerShell, it would look something like this

    , @([PSCustomObject]@{
        common = [PSCustomObject]@{
            attributes = [PSCustomObject]@{
                logtype  = 'accesslogs'
                service  = 'login-service'
                hostname = 'login.example.com'
            }
        }
        logs   = @(
            [PSCustomObject]@{
                message = "user 'xyz' logged in"
            },
            [PSCustomObject]@{
                message    = "User 'xyz' logged out"
                attributes = [PSCustomObject]@{
                    auditId = 123
                }
            }
        )
    }) 
    

    If you pipe that to | ConvertTo-Json -Depth 4 you will get a similar output to your example json

    [
      {
        "common": {
          "attributes": {
            "logtype": "accesslogs",
            "service": "login-service",
            "hostname": "login.example.com"
          }
        },
        "logs": [
          {
            "message": "user 'xyz' logged in"
          },
          {
            "message": "User 'xyz' logged out",
            "attributes": {
              "auditId": 123
            }
          }
        ]
      }
    ]
    

    Note: The [PSCustomObject]s are optional. Straight hashtables @{} will work as well however the order of the object’s properties (key-value pairs) may not match what you intend. You may use ordered hashtables [ordered]@{} instead to circumvent that if you wish.

    Login or Signup to reply.
  3. The outer array is tricky. You can get it, if you don’t pipe the object array in. ConvertTo-JSON an array with a single item The single quotes will become u0027 unless you’re in powershell 7. Only a comma is needed to create arrays. The default depth of convertto-json is 2, which usually isn’t enough. Powershell 7 will warn a too low depth.

    $objectarray = ,[PSCustomObject]@{
        common = [PSCustomObject]@{
            attributes = [PSCustomObject]@{
                logtype  = 'accesslogs'
                service  = 'login-service'
                hostname = 'login.example.com'
            }
        }
        logs   = @(
            [PSCustomObject]@{
                message = "user 'xyz' logged in"
            },
            [PSCustomObject]@{
                message    = "User 'xyz' logged out"
                attributes = [PSCustomObject]@{
                    auditId = 123
                }
            }
        )
    }
    convertto-json $objectarray -depth 4
    
    [
      {
        "common": {
          "attributes": {
            "logtype": "accesslogs",
            "service": "login-service",
            "hostname": "login.example.com"
          }
        },
        "logs": [
          {
            "message": "user 'xyz' logged in"
          },
          {
            "message": "User 'xyz' logged out",
            "attributes": {
              "auditId": 123
            }
          }
        ]
      }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search