Add filepath to ConvertTo-HTML

Converting PowerShell data into an HTML report and save it to disk with no need for extra pipeline has long been my dream. Unfortunately, there’s no native Export-HTML cmdlet (unlike, say, Export-CSV), and ConvertTo-HTML does not have -Path parameter and only displays the html code on the screen (very useful ;)) unless you pipe it to Out-File.

So being inspired by Kirk adding parameters to Import-CSV and using PowerShell 2.0 code-snippets, I created my Export-HTML function, which behaves exactly like ConvertTo-HTML but adds optional -Path parameter to specify the output file.

Download it, copy/paste the function into PowerShell (or dot-source it, or include it in your PowerShell profile) and you will be able to do something like:

Get-Process | Export-Html -Path C:\pr.htm

or

Get-Process |
    Export-Html C:\pr.htm -Title My Processes

or

Get-Process |
    Export-Html C:\pr.htm -Property Name, Handles -Title My Processes

You can download the code here, or copy/paste it from the text below.

You may also consider renaming the function name from Export-HTML to ConvertTo-HTML (or use set-alias to make them the same thing), because the -Path parameter is optional, and old behavior of outputting HTML code to the console/pipeline is supported as well as all native parameters.

Here’s how I created this proxy function:

  1. Downloaded and installed PowerShell 2.0 code snippets.
  2. Used the function (proxy) snippet to generate the proxy for ConvertTo-
    HTML
    .
  3. Added Path to the parameters section:
  4.     [Parameter(Position=0)]
        [Alias('PSPath', 'FilePath')]
        [ValidateNotNullOrEmpty()]
        [System.String]
        ${Path},
    
  5. Added a variable to store modified PowerShell code to be executed:
  6. $scriptCmdPipeline = ''
  7. Added parameter handling in which I (if Path is present) append the Out-File code to the pipeline:
  8.         if ($Path) {
                $PSBoundParameters.Remove('Path') | Out-Null
                $scriptCmdPipeline += " | Out-File -FilePath $Path"
            }
    
  9. Got the original command-line for ConvertTo-HTML
  10.         $scriptCmd = {& $wrappedCmd @PSBoundParameters}
    
  11. And added this new pipeline to it:
  12.         $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
                    [string]$scriptCmd + $scriptCmdPipeline
                )
    

The rest was handled by the code snippet.

Here’s the resultant code:

#Requires -Version 2.0

<#
    Export-Html behaves exactly like native ConvertTo-HTML
    However it has one optional parameter -Path
    Which lets you specify the output file: e.g.
    Get-Process | Export-Html C:\temp\processes.html
#>

function Export-Html {
[CmdletBinding(DefaultParameterSetName='Page')]
param(
    [Parameter(ValueFromPipeline=$true)]
    [System.Management.Automation.PSObject]
    ${InputObject},

# Adding Path parameter 
# (made it Position 0, and incremented Position for others)
    [Parameter(Position=0)]
    [Alias('PSPath', 'FilePath')]
    [ValidateNotNullOrEmpty()]
    [System.String]
    ${Path},

    [Parameter(Position=1)]
    [ValidateNotNullOrEmpty()]
    [System.Object[]]
    ${Property},

    [Parameter(ParameterSetName='Page', Position=4)]
    [ValidateNotNullOrEmpty()]
    [System.String[]]
    ${Body},

    [Parameter(ParameterSetName='Page', Position=2)]
    [ValidateNotNullOrEmpty()]
    [System.String[]]
    ${Head},

    [Parameter(ParameterSetName='Page', Position=3)]
    [ValidateNotNullOrEmpty()]
    [System.String]
    ${Title},

    [ValidateSet('Table','List')]
    [ValidateNotNullOrEmpty()]
    [System.String]
    ${As},

    [Parameter(ParameterSetName='Page')]
    [Alias('cu','uri')]
    [ValidateNotNullOrEmpty()]
    [System.Uri]
    ${CssUri},

    [Parameter(ParameterSetName='Fragment')]
    [ValidateNotNullOrEmpty()]
    [Switch]
    ${Fragment},

    [ValidateNotNullOrEmpty()]
    [System.String[]]
    ${PostContent},

    [ValidateNotNullOrEmpty()]
    [System.String[]]
    ${PreContent})

begin
{
    try {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
        {
            $PSBoundParameters['OutBuffer'] = 1
        }
        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('ConvertTo-Html', 
            [System.Management.Automation.CommandTypes]::Cmdlet)
        
        # define string variable to become the target command line
        #region Initialize helper variable to create command
        $scriptCmdPipeline = ''
        #endregion

        # add new parameter handling
        #region Process and remove the Path parameter if it is present
        if ($Path) {
            $PSBoundParameters.Remove('Path') | Out-Null
            $scriptCmdPipeline += " | Out-File -FilePath $Path"
        }
        #endregion
        
        $scriptCmd = {& $wrappedCmd @PSBoundParameters}
        
        # redefine command invocation
        #region Append our pipeline command to the wrapped command script block
        $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
                [string]$scriptCmd + $scriptCmdPipeline
            )
        #endregion
        
        
        $steppablePipeline = 
          $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}

process
{
    try {
        $steppablePipeline.Process($_)
    } catch {
        throw
    }
}

end
{
    try {
        $steppablePipeline.End()
    } catch {
        throw
    }
}
<#

.ForwardHelpTargetName ConvertTo-Html
.ForwardHelpCategory Cmdlet

#>}

Hope you find this useful and it gets you the feature you wanted without waiting for PowerShell v3.😉

Tags: , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




My Recent Tweets

Legal

The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer - WSO2 or anyone else for that matter. All trademarks acknowledged.

© 2007-2014 Dmitry Sotnikov

October 2009
M T W T F S S
« Sep   Nov »
 1234
567891011
12131415161718
19202122232425
262728293031  

%d bloggers like this: