Search code examples
jsonrestpowershellapipscustomobject

Adding a timestamp in a JSON body


I am quite new to powershell and not used to it yet. I am trying to remote some of my servers in RealTime. For that I use a RestAPI that send me data on a JSON format (that Powershell automatically convert to a PSCustomObject).

The thing is that there is no field timestamp in my JSON/data API so I have had to add it. Unfortunately, JSON tools in powershell seems limited and I was not able to add it directly. I had to create a new PSCustomObject called timestamp and combine it with my data from the API.

Unfortunetaly the data then is not parsed correctly. I tring going through a string, an array of string, a hashtable. It was worst. Finally I downloaded a JSON.NET Framework which I am trying to work with now...

So here is the main code part :

Function Combine-Objects { 
    Param (
        [Parameter(mandatory=$true)]$Object1, 
        [Parameter(mandatory=$true)]$Object2
    )

    $arguments = [Pscustomobject]@() 
    foreach ( $Property in $Object1.psobject.Properties){
        $arguments += @{$Property.Name = $Property.value}  
    }

    foreach ( $Property in $Object2.psobject.Properties){
        $arguments += @{ $Property.Name= $Property.value}         
    }

    $Object3 = [Pscustomobject]$arguments

    return $Object3
    }

while (1) 
{
    $startpoint = "REST API URL"
    $endpoint = "POWER BI API URL"
    $response = Invoke-RestMethod -Method Get -Uri $startpoint 
    $timestamp=get-date -format yyyy-MM-ddTHH:mm:ss.fffZ 
    $response2 = [PsCustomObject]@{"timestamp"=$timestamp}
    $response3 = Combine-Objects -Object1 $response -Object2 $response2
    Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($response3))
}

Before combnining PSCustomObject I have :

    total     : 8589463552
    available : 5146566656
    percent   : 40,1
    used      : 3442896896
    free      : 5146566656

which gave me a correct JSON after converting it

    [
        {
            "total":  8589463552,
            "available":  5146566656,
            "percent":  40.1,
            "used":  3442896896,
            "free":  5146566656
        }
    ]

While after combining and adding a timestamp I have :

    Name                           Value                                                                                                                                                           
    ----                           -----                                                                                                                                                           
    total                          8589463552                                                                                                                                                      
    available                      5146566656                                                                                                                                                      
    percent                        40,1                                                                                                                                                            
    used                           3442896896                                                                                                                                                      
    free                           5146566656                                                                                                                                                      
    timestamp                      2019-10-09T22:17:18.734Z    

Which gave me after conversion :

    [
        {
            "total":  8589463552
        },
        {
            "available":  5146566656
        },
        {
            "percent":  40.1
        },
        {
            "used":  3442896896
        },
        {
            "free":  5146566656
        },
        {
            "timestamp":  "2019-10-09T22:17:18.734Z"
        }
    ]

While all I wanted was simply :

    [
     {
      "total" :98.6,
      "available" :98.6,
      "percent" :98.6,
      "used" :98.6,
      "free" :98.6,
      "timestamp" :"2019-10-11T09:21:04.981Z"
     }
    ]

Solution

  • I think you're looking at this the wrong way. Why not simply add the NoteProperty containing the DateTime string to the PSCustomObject and then convert it back to the json format?

    Something like this would be enough:

    $json = @"
     [
        {
             "total":  8589463552,
             "available":  5146566656,
             "percent":  40.1,
             "used":  3442896896,
             "free":  5146566656
         }
      ]
    "@
    
    $jsonConverted = $json | ConvertFrom-Json
        
    $params = @{
       NotePropertyName  = 'timestamp'
       NotePropertyValue = (Get-Date).ToString('yyyy-MM-ddTHH:mm:ss.fff')
    }
    $jsonConverted | Add-Member @params
        
    $newJson = $jsonConverted | ConvertTo-Json  
    $newJson
    

    This will result in the json object you're looking for:

    {
        "total":  8589463552,
        "available":  5146566656,
        "percent":  40.1,
        "used":  3442896896,
        "free":  5146566656,
        "timestamp":  "2019-10-11T13:33:05.673"
    }