Windows PowerShell: HTML Reports in PowerShell

You can actually use Microsoft Windows PowerShell cmdlets to generate HTML reports you can share with your colleagues.

Don Jones

Among its many powers, Windows PowerShell has the built-in ability to produce HTML output from its various cmdlets. Simply pipe the cmdlet output to ConvertTo-HTML, and pipe that output to Out-File to get it into a file. For example:

Get-WmiObject –Class Win32_Service | 
Select-Object –property Name,State |
Where-Object –Filter { $_.StartMode –eq 'Auto' –and $_.State –ne 'Running' } | 
ConvertTo-HTML | 
Out-File BadNews.html

That will give you a list of services that should be running, but are not. That’s something you might write to an intranet file server and have your help desk check every morning. By the way, when typing all that, the first four lines should end with the pipe character (|). The last line ends with a carriage return.

If you interactively type that into the shell, you’ll notice the prompt change to “>>” after you finish typing the first line’s pipe and carriage return. That’s OK. It means Windows PowerShell is waiting for you to type the next line. After typing the fourth and final line, press Enter twice to tell the shell you’re done and that you want it to execute the command.

One problem with the ConvertTo-HTML cmdlet, however, is that it’s only designed to deal with one type of output at a time. If you try to feed it numerous object types—services, processes or event log entries—it won’t properly format the output.

If you want to create a consolidated report of some kind, the trick is to use the different parameters of the cmdlet. For example, let’s say you want to produce a report that includes the previously mentioned “services that should be running, but aren’t.” You also want the page to list the 100 most recent security event log entries, all the processes the server is running and some basic information about the server itself.

You need to know two things: First, the –Fragment parameter of ConvertTo-HTML (which you’ll find in its help file) and second, the fact that the cmdlet doesn’t write HTML to a file.

As in my first example, the cmdlet puts the HTML into the pipeline—it takes a separate step to get it into a file. That seems cumbersome in the first example, but will give us the capability we need to do this:

$one = Get-WmiObject -class Win32_Service |
 Select-Object -property Name,State |
 Where-Object -filter { $_.Mode -eq 'Auto' -and $_.State -ne 'Running' } |
ConvertTo-HTML -Fragment 

$two = Get-EventLog -LogName Security -newest 100 |
ConvertTo-HTML -Fragment 

$three = Get-Process |
ConvertTo-HTML -Fragment 

$four = Get-WmiObject -class Win32_OperatingSystem |
 Select-Object -property Caption,BuildNumber,ServicePackMajorVersion,
 @{n='LastBootTime';e={$_.ConvertToDateTime($_.LastBootUpTime)}} |
ConvertTo-HTML -Fragment 

ConvertTo-HTML -Body "$one $two $three $four" -Title "Server Status" |
 Out-File c:\status.html

When typing that in, end each line with a pipe character except the last line, which just ends with a carriage return. This runs four distinct commands, each of which is retrieving a certain piece of information and converting it to an HTML fragment.

An HTML fragment is a long string of HTML that doesn’t include the header tags that make a complete page. In the last step, I’m simply jamming the HTML into the body of a complete page and outputting it to a file.

Try running that and see what you think. It’s quite plain. It’s a joke that Windows PowerShell is the only Microsoft product that outputs “clean” HTML, without adding any style or formatting. The downside is that “clean” HTML is pretty boring. That’s on purpose. You’re supposed to make it more attractive using a separate CSS file.

Within HTML, you’ll primarily apply formatting to HTML <td> tags. These contain the table rows. The <th> tags contain the column headers for the table. The <body> tag can provide a default format for the entire page. Create a text file named C:\Style.css and enter the following:

body {
font-family:Calibri;
 font-size:10pt;
}
th { 
background-color:black;
color:white;
}
td {
 background-color:#666;
color:black;
}
Now, I’ll simply modify my lastConvertTo-HTML command as follows:
ConvertTo-HTML -Body "$one $two $three $four" -Title "Server Status" -CssUri c:\style.css |
 Out-File c:\status.html

That should take two lines of text to type, and once again, the first line ends at the pipe character. Try running all that. You’ll find a more nicely formatted output. Unfortunately, CSS doesn’t provide a way to apply style to alternating table rows, at least not in the way that Windows PowerShell produces the HTML output.

You can use the –PreContent and –PostContent parameters of ConvertTo-HTML to add section headings and any other text. This can help make the report more readable. It will display any string passed to –PreContent before the table. Text sent to –PostContent will display after the table. You can find examples of these by running Help ConvertTo-HTML
–example in the shell.

This is a great example of how you can use Windows PowerShell to produce helpful reports to share with your colleagues. It doesn’t take a lot of extra work to create decent-looking HTML output. By saving the pages to an intranet file server, you make them accessible to coworkers, managers and anyone else who might need them.

Don Jones

Don Jones is a Microsoft MVP Award recipient and author of “Learn Windows PowerShell in a Month of Lunches” (Manning Publications Co., 2010), a book designed to help any administrator become effective with Windows PowerShell. Jones also offers public and on-site Windows PowerShell training. Contact him through his Web site at ConcentratedTech.com.