Windows PowerShell Tip of the Week

Here’s a quick tip on working with Windows PowerShell. These are published every week for as long as we can come up with new tips. If you have a tip you’d like us to share or a question about how to do something, let us know.

Find more tips in the Windows PowerShell Tip of the Week archive.

Creating Formatted HTML Output

Pity the poor old cmdlet ConvertTo-HTML. When Windows PowerShell was first released everyone was excited about ConvertTo-HTML; after all, this cmdlet promised to make it easy to display script output as an HTML page. And, to its credit, ConvertTo-HTML delivered; for example, this simple little script returns information about the services running on a computer, saves that information to a .HTM file, and then displays that file in a Web browser:

Get-Service | Select-Object Status, Name, DisplayName | ConvertTo-HTML | Out-File C:\Scripts\Test.htm

Invoke-Expression C:\Scripts\Test.htm

So what’s wrong with that? Well, nothing, really. Except for the fact that the aesthetic quality of the resulting Web page does leave a little something to be desired:

That’s not necessarily bad, but it’s not really all that good, either. But, then again, that’s pretty much the best that ConvertTo-HTML can do.

Unless, of course, you give ConvertTo-HTML some help.

Using the –head Parameter

As it turns out, ConvertTo-HTML includes a parameter (-head) that enables you to assign HTML tagging to the the <head> section of your HTML page. That might not sound like that big of a deal; after all, the <head> section is often used to do nothing more than assign a title to your Web page. But let’s put it this way: you can do a lot more with the <head> section of an HTM file than simply use it to assign a title to your Web page.

Like what? Well, one very important thing you can do in the <head> section is assign styles. In turn, styles enable you to automatically change the formatting of objects that appear on the page. For example, each Web page includes a <body> element that controls the page background; unless you modify this element your page will use the default background (white). So how do you modify the <body> element and thus make the background a different color? One way is to insert a <style> section in the <head> section of the page:

<style>
    BODY
    {background-color:peachpuff;}
</style>

This tagging assigns a new background color (peachpuff) to the <body> element; any instances of this element that appear on the page will have peachpuff as the background color.

Note. Of course, there will be only one instance of the <body> element per page. However, if you assigned a style to say, the <p> element, then all the paragraphs on the page would inherit this style.

That’s nice, but what does any of it have to do with the ConvertTo-HTML cmdlet? Before we answer that question, let’s take a look at another PowerShell script:

$a = "<style>BODY{background-color:peachpuff;}</style>"

Get-Service | Select-Object Status, Name, DisplayName | ConvertTo-HTML -head $a | Out-File C:\Scripts\Test.htm

Invoke-Expression C:\Scripts\Test.htm

In this script we’re once again retrieving service information, saving that information as an HTML file, then using the Invoke-Expression cmdlet to open that file in a Web browser. However, this particular script adds a special little twist. Notice what we did in the very first line; we took the <style> tagging used to modify the background color of the <body> element and assigned that tagging to a variable named $a:

$a = "<style>BODY{background-color:peachpuff;}</style>"

In other words, the variable $a now contains the exact HTML tagging required to assign a style to the <body> element. With that in mind, we then added the –head parameter when we called ConvertTo-HTML, passing $a as the parameter value:

ConvertTo-HTML -head $a

Why did we do that? That’s easy: this causes the <head> section of the resulting HTML page to contain the information stored in $a, information that just happens to assign peachpuff as the document’s background color. The net result? This:

Well, what do you know? The style was applied, and our background color changed to peachpuff.

You know, you’re right: that is pretty cool. But now take a gander at this script:

$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;}"
$a = $a + "</style>"

Get-Service | Select-Object Status, Name, DisplayName | ConvertTo-HTML -head $a | Out-File C:\Scripts\Test.htm

Invoke-Expression C:\Scripts\Test.htm

Without going into enormous detail, what we’ve done here is define some additional styles beyond the <body> element; in particular, we’ve defined styles for the <table> element, the <th> (table heading) element, and <td> (table cell) element. These styles enable us to put a nice border around our table and around each of the cells in that table:

Not bad, huh? Once again, all the appropriate elements automatically inherited the corresponding styles; for example, all the table cells now have a one-pixel black border around them. And before you ask, yes, as far as we know you can add any style information you want to the –head parameter.

For example, here’s a modified version that does just that; it adds even more style information to the –head parameter:

$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:palegoldenrod}"
$a = $a + "</style>"

Get-Service | Select-Object Status, Name, DisplayName | ConvertTo-HTML -head $a | Out-File C:\Scripts\Test.htm

Invoke-Expression C:\Scripts\Test.htm

This time around we’ve made thistle the background color of our table header (background-color:thistle) and made PaleGoldenrod the background color of our table cells (background-color:palegoldenrod). Now take a look at the kind of Web page ConvertTo-HTML can generate for us:

Maybe not the best color combination in the world, but you get the idea.

But wait, there’s more. In addition to using the –head parameter you can also use the –body parameter and add additional information to the body of your Web page. Information such as? Well, how about a nice big heading for the page:

To get that heading all we had to do was add the HTML tagging for creating an <H2> head:

ConvertTo-HTML -head $a -body "<H2>Service Information</H2>"

The entire script looks like this:

$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"
$a = $a + "</style>"

Get-Service | Select-Object Status, Name, DisplayName |
ConvertTo-HTML -head $a &45;body "<H2>Service Information</H2>" |
Out-File C:\Scripts\Test.htm

Invoke-Expression C:\Scripts\Test.htm

Note. For more information on using the –body parameter, take a look at the article Saving Data as an HTML File in our Task-Based Guide to Windows PowerShell Cmdlets.

All in all those are some pretty nice Web pages, and they were each created by simply adding a few style tags to ConvertTo-HTML. Looks like we owe ConvertTo-HTML an apology, don’t we?

See you all next week.