powershellpscustomobject

Adding additional values to property of a PSCustomObject


I have three objects created that contain data from a parsed Json file.

#Get list of synthetic monitors by name
$executedMonitors = $json.result.data.dimensionMap."dt.entity.synthetic_test.name"
Write-Output $executedMonitors

#Get list of HTTP monitors by name
$httpExecutedMonitors = $json.result.data.dimensionMap."dt.entity.http_check.name"
Write-Output $httpExecutedMonitors

#Get list of synthetic & http monitors values
$Values = @($json.result.data.values)
Log "Values of executed synthetics:  ($Values)"

This is where the PASS/FAIL status is set using the $Values object.

##Checks "Values" value.  If greater/equal to 1 add property or PASS, else add property FAIL
$condition = '1'
try {
    ForEach ($value in $Values) {
        if ($value -ge $condition) {
            $value | Add-Member -NotePropertyName passFail -NotePropertyValue PASS
        }
        else {
            $value | Add-Member -NotePropertyName passFail -NotePropertyValue FAIL
        }
    }
}
catch {
    Log 'No failures occured'
}

At first, I only was using the objects $executedMonitors & $Values and added all the values to a custom ps object, shown below, and then formatted to a HTML table.

$i = 0
$report = 
if ($null -ne $executedMonitors) {
    foreach ($executedMonitor in $executedMonitors) {
        [pscustomobject] @{
            Application = $executedMonitor
            Status      = $Values[$i++].passFail
        }
}
}

Now, I would like to add the additional values from the $httpExecutedMonitors to the $report object 'Application' property, but am unable to do so without multiple additional values printing to the HTML table.

I have tried to add the additional values to the 'Application' property by creating an array and trying to add a new object:

$i = 0
$report =@()
$report += 
if ($null -ne $executedMonitors) {
    foreach ($executedMonitor in $executedMonitors) {
        [pscustomobject] @{
            Application = $executedMonitor
            Status      = $Values[$i++].passFail
        }
}
}

#testing
$report +=
foreach ($httpmonitor in $httpExecutedMonitors) {
   New-Object -TypeName psobject -Property @{Application = $httpmonitor}
}

as well as creating two separate psobjects and then trying to combine.

Sample json file that contains objects first created:

{
    "totalCount": 168,
    "nextPageKey": null,
    "resolution": "Inf",
    "result": [
        {
            "metricId": "(builtin:synthetic.browser.success:filter(and(or(in(\"dt.entity.synthetic_test\",entitySelector(\"type(synthetic_test),tag(~\"API~\")\"))))):splitBy(\"dt.entity.synthetic_test\"):names:sort(dimension(\"dt.entity.synthetic_test.name\",ascending))):names",
            "dataPointCountRatio": 2.004E-4,
            "dimensionCountRatio": 0.00167,
            "data": [
                {
                    "dimensions": [
                        "ADR Timeliness Calculator",
                        "SYNTHETIC_TEST-1E31363E09760539"
                    ],
                    "dimensionMap": {
                        "dt.entity.synthetic_test": "SYNTHETIC_TEST-1E31363E09760539",
                        "dt.entity.synthetic_test.name": "ADR Timeliness Calculator"
                    },
                    "timestamps": [
                        1711512000000
                    ],
                    "values": [
                        2
                    ]
                } 
            ]
        },
        {
            "metricId": "(builtin:synthetic.http.resultStatus:filter(and(or(in(\"dt.entity.http_check\",entitySelector(\"type(http_check),tag(~\"API~\")\"))))):splitBy(\"dt.entity.http_check\"):names:sort(dimension(\"dt.entity.http_check.name\",ascending)):limit(20)):names",
            "dataPointCountRatio": 1.2E-6,
            "dimensionCountRatio": 1.0E-5,
            "data": [
                {
                    "dimensions": [
                        "SNAP",
                        "HTTP_CHECK-BD16645521BF003A"
                    ],
                    "dimensionMap": {
                        "dt.entity.http_check.name": "SNAP",
                        "dt.entity.http_check": "HTTP_CHECK-BD16645521BF003A"
                    },
                    "timestamps": [
                        1711512000000
                    ],
                    "values": [
                        1
                    ]
                }
            ]
        }
    ]
}

Sample HTML output with failing code attempt: $executedMonitors $HttpExecutedMonitors with multiple spaces

I am unsure if I need to change how the objects $executedMonitors & $httpExecutedMonitors & $Values are configured with the additional metricID data from the Json or if my pscustomobject can be adjusted.


Solution

  • Seems like you could simplify your code by using PSMemberInfoCollection<T>.Match to get the property value used in Application property:

    $condition = 1
    
    $json.result.data | ForEach-Object {
        $status = 'FAIL'
        if ($_.values[0] -gt $condition) {
            $status = 'PASS'
        }
    
        [pscustomobject]@{
            Application = $_.dimensionmap.PSObject.Properties.Match('*.name').Value
            Status      = $status
        }
    }
    

    This assuming that these properties always end with .name. From the above would be:

    Application               Status
    -----------               ------
    ADR Timeliness Calculator PASS
    SNAP                      FAIL
    

    And converting this to HTML should work just fine using ConvertTo-Html.