0

I am looking use PowerShell to output some JSON that looks like this for use with a Python script:

 {
"run_date": "2020-08-27",
"total_queries": 4,
"number_results": 3,
"number_warnings": 1,
"number_errors": 5,
"build_url": "https://some-url.com",
"queries":{
    "query_a":{
        "database_a": "102 rows",
        "database_b": "Error: See pipeline logs for details"
    },
    "query_b": "No results",
    "query_c": {
        "database_a": "Warning: Number of results exceeded maximum threshold - 6509 rows",
        "database_c": "Error: See pipeline logs for details",
        "database_d": "Error: See pipeline logs for details"
    }
} }

(Ignore the above closing bracket, it won't format properly on here for some reason).

I am using a foreach loop within PowerShell to run each of these queries sequentially depending on which databases they need to be ran on.

I know in Python I can create a template of the JSON like so:

options = {
'run_date': os.environ['SYSTEM_PIPELINESTARTTIME'].split()[0],
'total_queries': 0,
'number_results': 0,
'number_warnings': 0,
'number_errors': 0,
'build_url': 'options = {
'run_date': os.environ['SYSTEM_PIPELINESTARTTIME'].split()[0],
'total_hunts': 0,
'number_results': 0,
'number_warnings': 0,
'number_errors': 0,
'build_url': 'https://some-url.com',
'queries': {} }

and then use something like:

options['queries'][filename][database] = '{} rows'.format(len(data))

To add data into the Python dictionaries.

I've tried using nested PSCustomObjects but I end up with a conflict when different queries are being ran on the same database, so its trying to add a value to the PSCustomObject with the same Key. I would like to know if there is a nice 'native' way to do this in PowerShell like there is in Python.

iRon
  • 20,463
  • 10
  • 53
  • 79
takeoff127
  • 43
  • 5

2 Answers2

0

Turns out I was just being a bit of an idiot and not remembering how to work with PowerShell objects.

Ended up first adding all the query names into the parent object like so:

foreach($name in $getqueries){
$notiObj.queries | Add-Member -NotePropertyName $name.BaseName -NotePropertyValue ([PSCustomObject]@{})}

Then adding in info about the queries themselves within the loop:

$notificationObj.queries.$queryName | Add-Member -NotePropertyName $database -NotePropertyValue "$($dataTable.Rows.Count) Rows" 
takeoff127
  • 43
  • 5
0

If the required end-result is a Json file, there is actually no need to work with complex (and rather fat) [PSCustomObject] types. Instead you might just use a [HashTable] (or an ordered dictionary by just prefixing the hash table, like: [Ordered]@{...})

To convert hash tables from your Json file, use the ConvertFrom-Json -AsHashTable parameter (introduced in PowerShell 6.0). To build a template (or just understand the PowerShell format), you might want to use this ConvertTo-Expression cmdlet:

$Json | ConvertFrom-Json -AsHashTable | ConvertTo-Expression

@{
        'number_errors' = 5
        'number_warnings' = 1
        'queries' = @{
                'query_b' = 'No results'
                'query_a' = @{
                        'database_a' = '102 rows'
                        'database_b' = 'Error: See pipeline logs for details'
                }
                'query_c' = @{
                        'database_a' = 'Warning: Number of results exceeded maximum threshold - 6509 rows'
                        'database_d' = 'Error: See pipeline logs for details'
                        'database_c' = 'Error: See pipeline logs for details'
                }
        }
        'build_url' = 'https://some-url.com'
        'run_date' = '2020-08-27'
        'number_results' = 3
        'total_queries' = 4
}

Meaning you can assign this template to $Options as follows:

$Options = @{
        'number_errors' = 5
        'number_warnings' = 1
        'queries' = @{ ...

And easily change your properties in your nested objects, like:

$Options.Queries.query_c.database_d = 'Changed'

Or add a new property to a nested object:

$Options.Queries.query_a.database_c = 'Added'

Which result in:

$Options | ConvertTo-Json

{
  "run_date": "2020-08-27",
  "queries": {
    "query_a": {
      "database_c": "Added",
      "database_b": "Error: See pipeline logs for details",
      "database_a": "102 rows"
    },
    "query_b": "No results",
    "query_c": {
      "database_c": "Error: See pipeline logs for details",
      "database_d": "Changed",
      "database_a": "Warning: Number of results exceeded maximum threshold - 6509 rows"
    }
  },
  "number_results": 3,
  "build_url": "https://some-url.com",
  "total_queries": 4,
  "number_errors": 5,
  "number_warnings": 1
}
iRon
  • 20,463
  • 10
  • 53
  • 79