10

#PSTip Fixing the output of ConvertTo-Html

When you export PowerShell objects to HTML, using the ConvertTo-Html cmdlet, and HTML links are present as the values of the object, ConvertTo-Html doesn’t render them as HTML links. To illustrate, the following snippet creates a table of all cmdlet names (to save space I selected just the first 3) and their online help version.

$helpTbl = Get-Command -CommandType Cmdlet |
Where-Object {$_.HelpUri} |
Select Name,@{n='HelpUri';e={"<a href='$($_.HelpUri)'>$($_.HelpUri)</a>"}} -First 3 |
ConvertTo-Html

$helpTbl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/></colgroup>
<tr><th>Name</th><th>HelpUri</th></tr>
<tr><td>Add-Computer</td><td>&lt;a href=&#39;http://go.microsoft.com/fwlink/?LinkID=135194&#39;&gt;http://go.microsoft.com/fwlink/?LinkID=135194&lt;/a&gt;</td></tr>
<tr><td>Add-Content</td><td>&lt;a href=&#39;http://go.microsoft.com/fwlink/?LinkID=113278&#39;&gt;http://go.microsoft.com/fwlink/?LinkID=113278&lt;/a&gt;</td></tr>
<tr><td>Add-History</td><td>&lt;a href=&#39;http://go.microsoft.com/fwlink/?LinkID=113279&#39;&gt;http://go.microsoft.com/fwlink/?LinkID=113279&lt;/a&gt;</td></tr>
</table>
</body></html>

Notice that some characters were converted into HTML character entities. Character entities are special reserved characters in HTML. In our example, the less than (<), greater than (>), or (‘) signs were converted into their respective entities so the browser can display them ‘as-is’ and not mix them with HTML tags.

That’s nice but it defeats our purpose of making the links clickable. Here’s how the links look when exported to a web page:

HelpUri1

There is no parameter on the ConvertTo-Html cmdlet to prevent the conversion from happening. To resolve that we can use the HtmlDecode method to convert the entities back to their HTML equivalents.
To use the HtmlDecode method we first need to load the System.Web assembly.

Add-Type -AssemblyName System.Web
[System.Web.HttpUtility]::HtmlDecode($cmd)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>HTML TABLE</title> </head><body> <
table> <colgroup><col/><col/></colgroup> <tr><th>Name</th><th>HelpUri</th></tr> <tr><td>Add-Computer</td><td><a href='http://go.microsoft.com/fwlink/?LinkID=135194'>http://go.microsoft.com/fwlink/?LinkID
=135194</a></td></tr> <tr><td>Add-Content</td><td><a href='http://go.microsoft.com/fwlink/?LinkID=113278'>http://go.microsoft.com/fwlink/?LinkID=113278</a></td></tr> <tr><td>Add-History</td><td><a href='
http://go.microsoft.com/fwlink/?LinkID=113279'>http://go.microsoft.com/fwlink/?LinkID=113279</a></td></tr> </table> </body></html>

The output is not as pretty as ConvertTo-Html output but it does exactly what we wanted to–no HTML entities are present. Let’s have a look of the result in a browser:

$helpTbl = Get-Command -CommandType Cmdlet |
Where-Object {$_.HelpUri} |
Select Name,@{n='HelpUri';e={"<a href='$($_.HelpUri)'>$($_.HelpUri)</a>"}} -First 3 |
ConvertTo-Html

Add-Type -AssemblyName System.Web
[System.Web.HttpUtility]::HtmlDecode($helpTbl) | Out-File d:\temp\PSCommands.html
Invoke-Item d:\temp\PSCommands.html

HelpUri2

Filed in: Columns, Tips and Tricks Tags: , ,

10 Responses to "#PSTip Fixing the output of ConvertTo-Html"

  1. Other says:

    What’s wrong with using -replace ‘&lt’,'<'

    What's wrong with using -replace 'lt’,'<'

    Hey, your website is doing the opposite. When I type "lt” it really puts a ‘<'.

    Far out it even does closing tags.

    • ShayLevy says:

      There’s nothing wrong with -replace as long as you know all entities and what to replace them with. Sounds like an overkill for me when you have a native class that can do all of that for you in one line of code instead of a lot of replace operations.

  2. Tony Fountain says:

    Even though this is a year old, you can still use both methods (ConvertTo-Html and HtmlEncode). All you have to do is pipe the results of ConvertTo-Html to a ForEach loop that looks something like this: ForEach { [System.Web.HttpUtility]::HtmlDecode($PSItem) }

  3. brendan62269 says:

    Thanks Shay, very good tip!

  4. Roger says:

    Excellent – This also works for nested tables for custom objects
    Thanks!

  5. Derek says:

    I am trying to achieve the same but the link shows up as –

    31

    Code –

    $b = $b + @{Label=’ID’;Expression={‘a href=”http://bugzilla.sync.net/show_bug.cgi?id=”$Bug_Id”>$(Bug_Id)‘}}

    Add-Type -AssemblyName System.Web
    [System.Web.HttpUtility]::HtmlDecode($b)

  6. Derek says:

    The link is showing us as –

    “a href=’http://bugzilla.4yoursoul.net/show_bug.cgi?id’+’=’+’Bug_id’>27361</a"

    Note – I have purposely removed the start and end angular brackets as the page is rendering the hyperlink as desired.

Leave a Reply

Submit Comment

© 2016 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: