Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun Text to HTML

Posted on August 22, 2014August 29, 2014

htmlI love being able to create HTML documents from PowerShell commands. The Convertto-HTML cmdlet will happily turn any object into an HTML table using whatever properties you specify. Plus you can do all sorts of fancy things such as embedding a style sheet in the header, creating HTML fragments and inserting additional HTML elements. Today's Friday Fun takes ConvertTo-HTML a bit further. As always what I have isn't necessarily a production-worthy script but hopefully it will serve as a learning tool.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

My idea was to take a text file such as a script and turn it into an HTML document using alternate shaded rows for the style. I already had a style header from some other scripts so that part was easy. My first attempt was to simply get the content of the file and convert to HTML.

get-content .\XMLDemo.txt | convertto-html

But there is a problem which you'll see if you try this at home. ConvertTo-HTML is looking for a set of object properties, and the the contents of a file don't have any. Or to put it another way, I need to turn the contents of the file into an object. Since I knew I wanted to include the line number, I figured I could use the [pscustomobject] type that was introduced in PowerShell 3.0.

get-content .\XMLDemo.txt | foreach -begin {$i=0} -process { 
#create a custom object out of each line of text
$i++
[pscustomobject]@{Line=$i;" "=$_}
} 

When run, I each line is turned into a custom object with a property for the Line number and a property for the value of each line. Normally, you would want to give your property a name, but in this case I don't want a property name so I'm using a blank. You'll see why eventually. Now I can pipe this to ConvertTo-HTML and get the output I'm expecting. That's the crux of the script. Here's the complete function, ConvertTo-HTMLListing

#requires -version 3.0

Function ConvertTo-HTMLListing {

<#
.Synopsis
Convert text file to HTML listing
.Description
This command will take the contents of a text file and create an HTML document complete with line numbers.

There are options to suppress the line numbers and to skip any blank lines. The command is intended to convert one file at a time although you can pipe a file name to the command.
.Example
PS C:\> ConvertTo-HTMLListing -path c:\scripts\myscript.ps1 | out-file d:\MyScript.htm
.Example
PS C:\> dir c:\work\myfile.ps1 | ConvertTo-HTMLListing | Out-file d:\myfile.htm
.Example
PS C:\> foreach ($file in (dir c:\work\*.txt)) { ConvertTo-HTMLListing $file.fullname | Out-File D:\$($File.basename).htm }

Create an HTML file for each text file in C:\work.
.Notes
Last Updated: 8/22/2014
Version     : 0.9

Learn more:
 PowerShell in Depth: An Administrator's Guide (http://www.manning.com/jones6/)
 PowerShell Deep Dives (http://manning.com/hicks/)
 Learn PowerShell in a Month of Lunches (http://manning.com/jones3/)
 Learn PowerShell Toolmaking in a Month of Lunches (http://manning.com/jones4/)
 
  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

.Link
https://jdhitsolutions.com/blog/2014/08/friday-fun-text-to-html

.Link
ConvertTo-HTML
#>
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="Enter the path to the file",
ValueFromPipeline,ValueFromPipelineByPropertyName)]
[alias("PSPath")]
[ValidateScript({Test-Path $_})]
[string]$Path,
[switch]$SkipBlankLines,
[switch]$NoLineNumber
)

Begin {
    Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"  

    $head = @'
<Title>Script Listing</Title>
<style>
body { background-color:#FFFFFF;
       font-family:Consolas;
       font-size:12pt; }
td, th { border:0px solid black; 
         border-collapse:collapse; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 0px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { margin-left:25px; }
h2 {
 font-family:Tahoma;
}
.footer 
{ color:green; 
  margin-left:25px; 
  font-family:Tahoma
}

</style>
'@

} #begin

Process {
    $file = Resolve-Path -Path $Path
    Write-Verbose "Processing $($file.providerpath)"
    $body = "<H2>$($file.providerpath)</H2>"
    $content = Get-Content -Path $file

    if ($SkipBlankLines) {
        #filter out blank lines
        Write-Verbose "Skipping blanks"
        $content = $content | where {$_ -AND $_ -match "\w"}
    }

    Write-Verbose "Converting text to objects"
    $processed = $content | foreach -begin {$i=0} -process { 
    #create a custom object out of each line of text
    $i++
    [pscustomobject]@{Line=$i;" "=$_}
    } 

    if ($NoLineNumber) {
      $processed = $processed | Select " "
    }

    Write-Verbose "Creating HTML"
    $body+= $processed | ConvertTo-Html -Fragment | foreach {
    #convert spaces to HTML spaces
    $_.replace(" ","&nbsp;")
    }

    $post = "<br><div class='footer'>$(Get-Date)</div>"
    #create the HTML output and write to the pipeline
    ConvertTo-HTML -Head $head -Body $body -PostContent $post 
} #process

End {    
    Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
} #end

} #end function

This function takes a file name and turns the text contents into an HTML document.

convertto-htmllisting

The function includes an embedded style sheet which is what allows me to use different fonts for the different sections as well as the alternating rows. The only other "trick" is that I'm replacing spaces in the original text with the HTML equivalent.

 $body+= $processed | ConvertTo-Html -Fragment | foreach {
    #convert spaces to HTML spaces
    $_.replace(" ","&nbsp;")
    }

This is why it is helpful for PowerShell cmdlets to only do one thing. If ConvertTo-HTML automatically wrote to a file I'd have to jump through more hoops. But it doesn't. This function as well only writes the HTML to the pipeline. You will still need to pipe it to Out-File to save. There are some examples in the comment-based help.

You'll notice in the output that the table has a header for the line number and nothing for the line of text. That's why I used a space for the property name in my pscustomobject.

The only other features I have are the options to skip blank lines and line numbers.

Now before you start saying, "Yeah but what about...", I know there are other techniques and ISE add-ons to turn scripts into complete and colorized HTML files. You can also simply open the file in a browser as well and have it displayed as text. My function is really aimed as a teaching tool, although it could be kind of cool to have an HTML based library of your PowerShell scripts.

So was this fun? Did you learn something new? If not, there's always next week. Enjoy your weekend.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

4 thoughts on “Friday Fun Text to HTML”

  1. Ray Romero says:
    August 25, 2014 at 1:39 pm

    I like it but I get the following: , : The “=” operator is missing after a named argument.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    , : The “=” operator is missing after a named argument.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    , : The “=” operator is missing after a named argument.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    , : The “=” operator is missing after a named argument.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    1. Jeffery Hicks says:
      August 25, 2014 at 2:21 pm

      Do you get this with every file you try to convert? You are going to have to show me the syntax you are using or more context.

  2. Ray says:
    August 25, 2014 at 7:20 pm

    I entered one of the examples.

    foreach ($file in (dir *.txt)) { .\ConvertTo-HTMLListing $file.fullname | Out-File D:\$($File.basename).htm }

    1. Jeffery Hicks says:
      August 26, 2014 at 7:56 am

      Did you dot source the script to load the function first?

      There might also be a typo. Remove the relative path to ConvertTo-HTMLListing and try this:
      foreach ($file in (dir *.txt)) { ConvertTo-HTMLListing $file.fullname | Out-File D:\$($File.basename).htm }

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d