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 via web from blindpete’s posterous

    • Share/Bookmark
    This entry was posted in Ramble. Bookmark the permalink.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>