Email Reporting with PowerShell

I’m a huge fan of reports when it comes to my IT infrastructure. I like being able to tangibly see numbers change over time, or even better, stay the same.

One of the ways I accomplish this is by setting up HTML reporting in almost all of my production scripts. It’s great to write a script that automatically prunes a directory or makes changes to a config that was mistakenly changed, but I want to be notified about it when it happens.

PowerShell includes the -BodyAsHTML parameter with the Send-MailMessage cmdlet, which allows us to easily build dynamic reports while a script is running.

But first, we need to set a variable with some necessary HTML.

$HTMLTop="<html><head><style>table{border: 1px solid black; border-collapse: collapse;}th{border: 1px solid black; border-collapse: collapse;}td{border: 1px solid black; border-collapse: collapse;}</style></head><body>"

In $HTMLTop, we are doing a few things:

  1. We are declaring the following text to be HTML
  2. We are declaring a <head> section and defining a style for the <table> tag so that any table(s) we create will have borders and pop out in the report.
  3. We are declaring a <body> tag, so that we can start building the rest of our HTML output.

Now, to create an HTML table, we need to create a second variable:

$HTMLTable="<p><table><th>ColumnHeader1</th><th>ColumnHeader2</th><th>ColumnHeader3</th>"

$HTMLTable defines the top row (headers) of our HTML table. Now we just need to add content. As your script processes and results are generated, you just need to add new rows to $HTMLTable.

$HTMLTable += "<tr><td>ColumnData1</td><td>ColumnData2</td><td>ColumnData3</td></tr>"

Note: This is just basic HTML, so you can add coloring to your reporting using inline CSS. For example:

<td style=color:green;font-weight:bold;>Success</td>

To close out your HTML table, append the closing tag to your existing variable:

$HTMLTable += "</table>

You can also create additional elements for your report:

$HTMLMessage = "<p>This report tracks disk usage</p>"

Now to put it all together and close out the HTML:

$HTMLFinal = $HTMLTop + $HTMLMessage + $HTMLTable + "</body></html>"

We now have a fully formed HTML report ($HTMLFinal) that we can use with the -Body parameter when we use Send-MailMessage.

Send-MailMessage -SMTPServer <your server> -To <smtp address> -From <smtp address> -Subject <your subject> -Body $HTMLFinal -BodyAsHTML

Here is an example email report from a script I wrote that reports on our VMware datastore utilization each morning: