简体   繁体   中英

Add Values into Nested Objects in PowerShell like you can in Python

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.

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" 

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM