Powershell 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:
[Parameter(Position=0)]
    [Alias('PSPath', 'FilePath')]
    [ValidateNotNullOrEmpty()]
    [System.String]
    ${Path},
  • Added a variable to store modified PowerShell code to be executed:
  • $scriptCmdPipeline = ''
  • Added parameter handling in which I (if Path is present) append the Out-File code to the pipeline:
  • if ($Path) {
                $PSBoundParameters.Remove('Path') | Out-Null
                $scriptCmdPipeline += " | Out-File -FilePath $Path"
            }
  • Got the original command-line for ConvertTo-HTML
  • $scriptCmd = {& $wrappedCmd @PSBoundParameters}
  • And added this new pipeline to it:
  • $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: , , , , , , ,
    Add to: | Technorati | Digg | del.icio.us | Yahoo | BlinkList | Spurl | reddit | Furl |

    Possibly related posts: (automatically generated)

    Going to add to my Script for sending via email as it keeps the formatting good :)

    Posted