Creating PDF files using PowerShell

Sometimes, you may want your scripts to produce output for management in a format other than plain text or Excel files (CSV). Thanks to various .NET PDF creation libraries, it is relatively simple to create PDF reports using PowerShell.

1. Download iTextSharp
**
**For this we will use the iTextSharp library, an open source .NET PDF creation library. Download it from https://sourceforge.net/projects/itextsharp

You only need two files: iTextSharp.xml and iTextSharp.dll

2. Adding the assembly
**
**After right clicking on the files, going to properties, and clicking Unblock, you can now import the assembly in PowerShell:

Add-Type -Path ".\itextsharp.dll"

3. Creating wrapper functions
**
**We will make some basic wrapper functions for the most popular actions: Setting up the PDF, adding a title, adding a text paragraph, adding an image and a table:

# Set basic PDF settings for the document
Function Create-PDF([iTextSharp.text.Document]$Document, [string]$File, [int32]$TopMargin, [int32]$BottomMargin, [int32]$LeftMargin, [int32]$RightMargin, [string]$Author)
{
    $Document.SetPageSize([iTextSharp.text.PageSize]::A4)
    $Document.SetMargins($LeftMargin, $RightMargin, $TopMargin, $BottomMargin)
    [void][iTextSharp.text.pdf.PdfWriter]::GetInstance($Document, [System.IO.File]::Create($File))
    $Document.AddAuthor($Author)
}

# Add a text paragraph to the document, optionally with a font name, size and color
function Add-Text([iTextSharp.text.Document]$Document, [string]$Text, [string]$FontName = "Arial", [int32]$FontSize = 12, [string]$Color = "BLACK")
{
    $p = New-Object iTextSharp.text.Paragraph
    $p.Font = [iTextSharp.text.FontFactory]::GetFont($FontName, $FontSize, [iTextSharp.text.Font]::NORMAL, [iTextSharp.text.BaseColor]::$Color)
    $p.SpacingBefore = 2
    $p.SpacingAfter = 2
    $p.Add($Text)
    $Document.Add($p)
}

# Add a title to the document, optionally with a font name, size, color and centered
function Add-Title([iTextSharp.text.Document]$Document, [string]$Text, [Switch]$Centered, [string]$FontName = "Arial", [int32]$FontSize = 16, [string]$Color = "BLACK")
{
    $p = New-Object iTextSharp.text.Paragraph
    $p.Font = [iTextSharp.text.FontFactory]::GetFont($FontName, $FontSize, [iTextSharp.text.Font]::BOLD, [iTextSharp.text.BaseColor]::$Color)
    if($Centered) { $p.Alignment = [iTextSharp.text.Element]::ALIGN_CENTER }
    $p.SpacingBefore = 5
    $p.SpacingAfter = 5
    $p.Add($Text)
    $Document.Add($p)
}

# Add an image to the document, optionally scaled
function Add-Image([iTextSharp.text.Document]$Document, [string]$File, [int32]$Scale = 100)
{
    [iTextSharp.text.Image]$img = [iTextSharp.text.Image]::GetInstance($File)
    $img.ScalePercent(50)
    $Document.Add($img)
}

# Add a table to the document with an array as the data, a number of columns, and optionally centered
function Add-Table([iTextSharp.text.Document]$Document, [string[]]$Dataset, [int32]$Cols = 3, [Switch]$Centered)
{
    $t = New-Object iTextSharp.text.pdf.PDFPTable($Cols)
    $t.SpacingBefore = 5
    $t.SpacingAfter = 5
    if(!$Centered) { $t.HorizontalAlignment = 0 }
    foreach($data in $Dataset)
    {
        $t.AddCell($data);
    }
    $Document.Add($t)
}

A module with the wrapper functions is available here: https://github.com/dendory/PowerShell-PDF

4. Sample script 1
**
**This script will create a PDF using some images of kittens (images to be downloaded separately):

$pdf = New-Object iTextSharp.text.Document
Create-PDF -Document $pdf -File "$PSScriptRoot\kittens-report.pdf" -TopMargin 20 -BottomMargin 20 -LeftMargin 20 -RightMargin 20 -Author "Patrick"
$pdf.Open()
Add-Title -Document $pdf -Text "Report about kittens" -Color "magenta" -Centered
Add-Text -Document $pdf -Text "Meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow"
Add-Image -Document $pdf -File "$PSScriptRoot\kitten1.jpg"
Add-Table -Document $pdf -Dataset @("Name", "Mittens", "Age", "1.5", "Fur color", "Black and white", "Favorite toy", "String") -Cols 2 -Centered
Add-Image -Document $pdf -File "$PSScriptRoot\kitten2.jpg"
Add-Table -Document $pdf -Dataset @("Name", "Achilles", "Age", "2", "Fur color", "Grey", "Favorite toy", "Shoes") -Cols 2 -Centered
Add-Text -Document $pdf -Text "Meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow meow"
$pdf.Close()

**5. Sample script 2

**This script will get a list of running processes and create a PDF with a table:

$pdf = New-Object iTextSharp.text.Document
Create-PDF -Document $pdf -File "C:\processes-report.pdf" -TopMargin 20 -BottomMargin 20 -LeftMargin 20 -RightMargin 20 -Author "Patrick"
$pdf.Open()
Add-Title -Document $pdf -Text "Running processes at $(Get-Date)" -Centered
$processes = @()
Get-Process | foreach { $processes += $_.Name; $processes += "" + $_.Path }
Add-Table -Document $pdf -Dataset $processes -Cols 2 -Centered
$pdf.Close()