Home > Blockchain >  Powershell - Convert an ordered nested dictionary to html
Powershell - Convert an ordered nested dictionary to html

Time:12-09

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 :

| 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  |

CodePudding user response:

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
  • Related