Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Powershell – Convert an ordered nested dictionary to html

I need to report the number of VM snapshots based on their age. For this, I constructed an ordered dictionary that contain another dictionary like this (json output):

    {
      "Less than 24h": {
        "Prod": 15,
        "Other": 11
      },
      "1 day": {
        "Prod": 29,
        "Other": 12
      },
      "2 days": {
        "Prod": 11,
        "Other": 0
      },
      "3 days and more": {
        "Prod": 0,
        "Other": 0
      }
    }

I need to convert it to html to be included in a mail.
I find how to convert a "simple" dictionary :

    $Body1 = $dict.GetEnumerator() | Select-Object Key,Value | ConvertTo-Html -Fragment | Out-String
    $Body1 = $Body1.Replace('Key','Days').Replace('Value','Number of Snapshot')

And that work fine, but not if the values are nested dictionaries.
For nested dictionary the output will be like this :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

| Days            | Number of Snapshot                             |
|-----------------|------------------------------------------------|
| Less than 24h   |`System.Collections.Specialized.OrderedDictionary`| 
| 1 day           |`System.Collections.Specialized.OrderedDictionary`|
| 2 days          |`System.Collections.Specialized.OrderedDictionary`|
| 3 days and more |`System.Collections.Specialized.OrderedDictionary`|

Is there a way to have a html output like this?

| Days            | Prod | Other |
|-----------------|------|-------|
| Less than 24h   |  15  |   11  | 
| 1 day           |  29  |   12  |
| 2 days          |  11  |    0  |
| 3 days and more |   0  |    0  |

>Solution :

One option is to pre-process your dictionary and convert it into something else that can be turned into html a bit easier:

$data = $dict.GetEnumerator() | foreach-object {
    new-object pscustomobject -property ([ordered] @{
        "Days"  = $_.Key
        "Prod"  = $_.Value.Prod
        "Other" = $_.Value.Other
    })
}

This will flatten your nested structure into this json-equivalent:

[
  {
    "Days": "2 days",
    "Prod": 11,
    "Other": 0
  },
  {
    "Days": "1 day",
    "Prod": 29,
    "Other": 12
  },
  {
    "Days": "Less than 24h",
    "Prod": 15,
    "Other": 11
  },
  {
    "Days": "3 days and more",
    "Prod": 0,
    "Other": 0
  }
]

And then you can just convert the whole thing in one go without -Fragment:

$Body1 = $data | ConvertTo-Html

which gives:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/></colgroup>
<tr><th>Days</th><th>Prod</th><th>Other</th></tr>
<tr><td>2 days</td><td>11</td><td>0</td></tr>
<tr><td>1 day</td><td>29</td><td>12</td></tr>
<tr><td>Less than 24h</td><td>15</td><td>11</td></tr>
<tr><td>3 days and more</td><td>0</td><td>0</td></tr>
</table>
</body></html>

or

Days Prod Other
2 days 11 0
1 day 29 12
Less than 24h 15 11
3 days and more 0 0
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading