Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!

ConvertTo-HTML Tips and Tricks

Everybody loves a nice HTML report. Am I right? Creating these reports in PowerShell is not that difficult. I thought I would offer up some tips and tricks you may not be aware of, including a few that I use all the time when I am creating reports. Some of these are documented in the help for ConvertTo-HTML. You do read the help, correct? Remember that ConvertTo-HTML does not create an actual file, just the HTML code. This is good for us. This means that we can modify the HTML on the fly and save the file when finished.



Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

Be Selective

The first, and perhaps most important tip, is to be selective. Let’s take a simple command and output like this one.

A simple PowerShell command (Image credit: Jeff Hicks)
A Simple PowerShell Command (Image credit: Jeff Hicks)

You want to create an HTML version of this, so you run a command like this:

Get-EventLog -list | convertto-html | out-file d:\temp\a.htm

When you open the file in your browser, things are not quite what you expected.

Converted output (Image credit: Jeff Hicks)
Converted Output (Image credit: Jeff Hicks)

This is because Convertto-Html, like Export-CSV and Export-Clixml, take the entire object. This is not just the default result you see on the screen. Remember, everything will be treated as a string. In my example, if I want a similar HTML file, I will have to recreate the output with Select-Object. This might require piping the original result to Get-Member to discover the “real” property names.

Get-Eventlog -List | Select @{Name="Max(K)";Expression = {$_.MaximumKilobytes }},
@{Name="Retain";Expression = {$_.MinimumRetentionDays }},
OverFlowAction,@{Name="Entries";Expression = {$_.entries.count}},
@{Name="Log";Expression = {$_.LogDisplayname}}

I always test without converting first.

Recreating output (Image credit: Jeff Hicks)
Recreating Output (Image credit: Jeff Hicks)

I get a list instead of a table but at least the properties are correct. Let’s recreate the HTML file by piping the above to Convert-HTML and then Out-File overwriting the original and useless file.

The revised file (Image credit: Jeff Hicks)
The Revised File (Image credit: Jeff Hicks)

This is much better compared to what I had originally. Although, since everything is being treated as a string, I can format the numeric values to look more like the original PowerShell output.

Get-Eventlog -List | Select @{Name="Max(K)";Expression = {"{0:n0}" -f $_.MaximumKilobytes }},
@{Name="Retain";Expression = {$_.MinimumRetentionDays }},
OverFlowAction,@{Name="Entries";Expression = {"{0:n0}" -f $_.entries.count}},
@{Name="Log";Expression = {$_.LogDisplayname}} | convertto-html -Title "Event Log Report" | out-file d:\temp\a.htm

I also went and added a title, so I get something more useful than HTML TABLE.

A better formatted report (Image credit: Jeff Hicks)
A Better Formatted Report (Image credit: Jeff Hicks)

Use Pre/Post Content

We are starting to build something with a bit more visual appeal. This leads me to another suggestion, take advantage of the pre and post content parameters.

When you pipe something to ConvertTo-HTML, the cmdlet generally creates a table. But you can insert additional HTML directives for things to put in before the main code and after. You can use as much html code as you want.

Get-Eventlog -List | Select @{Name="Max(K)";Expression = {"{0:n0}" -f $_.MaximumKilobytes }},
@{Name="Retain";Expression = {$_.MinimumRetentionDays }},
OverFlowAction,@{Name="Entries";Expression = {"{0:n0}" -f $_.entries.count}},
@{Name="Log";Expression = {$_.LogDisplayname}} | 
convertto-html -Title "Event Log Report" -PreContent "<H1>$($env:COMPUTERNAME)</H1>" -PostContent "<H5><i>$(get-date)</i></H5>" | 
out-file d:\temp\a.htm

I added an intro element using the H1 tag to display the computer name. Following the content, I am inserting the current date and time formatted with the H5 heading and italic tags.

Report with pre and post content (Image credit: Jeff Hicks)
Report with Pre and Post Content (Image credit: Jeff Hicks)

Of course, you can always specify the path to a CSS file.

Get-Eventlog -List | Select @{Name="Max(K)";Expression = {"{0:n0}" -f $_.MaximumKilobytes }},
@{Name="Retain";Expression = {$_.MinimumRetentionDays }},
OverFlowAction,@{Name="Entries";Expression = {"{0:n0}" -f $_.entries.count}},
@{Name="Log";Expression = {$_.LogDisplayname}} | 
convertto-html -Title "Event Log Report" -PreContent "<H1>$($env:COMPUTERNAME)</H1>" -PostContent "<H5><i>$(get-date)</i></H5>" -CssUri C:\scripts\text.css | 
out-file d:\temp\a.htm

With a style sheet (Image credit: Jeff Hicks)
With a Style Sheet (Image credit: Jeff Hicks)

If you want to play along at home, this is the CSS code I am using:

body { background-color:#E5E4E2;
       font-size:10pt; }
td, th { border:0px solid black; 
         white-space:pre; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 0px; margin: 0px ;white-space:pre; }
table { margin-left:25px; }
h2 {
{ color:green; 

I am using a file on my hard drive. This means that if anyone else were to look at the file, they would not get the same formatting. The solution is to use a CSS file path that everyone can reach. Check back later for the next article in this series.

Related Topics:


Don't have a login but want to join the conversation? Sign up for a Petri Account

Comments (1)

One response to “ConvertTo-HTML Tips and Tricks”

  1. Lex

    Article is missing images

Leave a Reply

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.


Sponsored By