Use CSS to style HTML reports in PowerShell

ConvertTo-HTML allows to add all kind of different elements into an HTML file. HTML files have a simple structure that usually include a head and a body. Those elements can be modified with ConvertTo-HTML parameters. Let us check the syntax of this cmdlet first (this cmdlet has two sets of parameters, we are using the first one):

ConvertTo-Html
              [-InputObject <PSObject>]
              [[-Property] <Object[]>]
              [[-Body] <String[]>]
              [[-Head] <String[]>]
              [[-Title] <String>]
              [-As <String>]
              [-CssUri <Uri>]
              [-PostContent <String[]>]
              [-PreContent <String[]>]
              [-Meta <Hashtable>]
              [-Charset <String>]
              [-Transitional]
              [<CommonParameters>]

When it comes to HTML, “The <head> element is a container for metadata (data about data)”. It typically contains information like scripts, character sets and style. Naturally, we need to find a way to modify the style of the resultant file and we can do that using CSS. There is three ways to include CSS in an HTML:

  • Inline: by setting the style attribute inside the HTML element tags.
  • Internal: with the style element inside the head tag.
  • External: by calling an external file with the CCS code in it.

Internal could be useful if you just want to stylish a single report. The downside is that it requires to hard code CSS inside the PS code, which may not be functional if you want to use the same style for different reports or if you want to just change the style in separate file instead of changing all your scripts. With that said, I will cover both ways here.

Internal CSS to style an HTML report

This method involves creating the set of rules for CSS inside the head element of the HTML. Turns out there is a parameter with the name -head available for ConvertTo-HTML. According to the documentation, -Head: “Specifies the content of the <HEAD> tag.” That is what we need since we want to include something inside <head>. But which elements should we style in the CSS code? If we check the -As parameter of ConvertTo-HTML we can see that the resultant object, the HTML, is formatted as a table by default (it can be a list too). With that in mind, we will be including rules for tags such as <table>, <tr>, <td> and <th> in our CSS.

The following CCS rule changes the font, borders, padding and width properties of a table (<table>) and table header (<th>) HTML elements:

<style>
table {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border: 1px solid black;
    border-collapse: collapse;
    width: 100%;
}
th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: center;
    background-color: #21943f;
    color: white;
}
</style>

To include that in our HTML from PS, we first have to create a variable with the CSS code and then pass it to the -Head parameter of ConvertTo-HTML:

$basicStyle = @"
<style>
table {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border: 1px solid black;
    border-collapse: collapse;
    width: 100%;
}
th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: center;
    background-color: #21943f;
    color: white;
}
</style>
"@

Get-Service | ConvertTo-Html -Head $basicStyle | Out-File servicesReport.html

The result will look like this:

servicesReport.html

External CSS to style an HTML report

Websites usually link different CSS styles from different sources and there is a parameter to do just that with ConvertTo-Html: -Cssuri. But we will try a slightly different approach here. We are going to create a standard .css file and then we will manipulate it a bit inside the PS code to do the same thing we did with the internal CSS.

In a .css file we save the following CSS rules (style.css in my case):

table {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border: 1px solid black;
    border-collapse: collapse;
    width: 100%;
}
th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: center;
    background-color: #21943f;
    color: white;
}

Since we are going to pass these CSS rules to the -Head parameter, we must include the <style> tag. We can do that with the following code:

$externalCSSFile = Get-Content -Path "D:\style.css" -Raw
$style = ("<style>`n") + $externalCSSFile + ("`n</style>")

Get-Service | ConvertTo-Html -Head $style | Out-File servicesReportExternalCSS.html

The resultant .html will have the same style that the internal .css. We took the code inside the .css, added the <style> tags and then pass it to the -Head parameter.

So now if we want to change something, we just change the contents of the style.css file instead of modifying the PS script. Here is an example of a set of rules I like to use for HTML reports:

    table {
        font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
        border-collapse: collapse;
        width: 100%;
    }
    th {
        padding-top: 12px;
        padding-bottom: 12px;
        text-align: center;
        background-color: #348dd8;
        color: white;
    }
    tr:nth-child(even) {
        background: #CCC;
        text-align: left;
    }
    tr:nth-child(odd) {
        background: #FFF;
        text-align: left;
    }

If you put that inside the .css file, your report will look like this one:

| Theme: UPortfolio