In the previous tip we explained how you can use PowerShell on Windows 10 and Windows Server 2016 to set up a PDF printer that prints anything to a PDF file, of course unattended. To make it really useful, let’s wrap it into a function called Out-PDFFile. Anything you pipe to this new command is turned into a PDF file.

Important: for this function to work, you must have set up the printer “PrintPDFUnattended” as instructed in the previous tip!

Here is the Out-PDFFile function:

function Out-PDFFile
{
    param
    (
        $Path = "$env:temp\results.pdf",

        [Switch]
        $Open
    )

    # check to see whether the PDF printer was set up correctly
    $printerName = "PrintPDFUnattended"
    $printer = Get-Printer -Name $printerName -ErrorAction SilentlyContinue
    if (!$?)
    {
        Write-Warning "Printer $printerName does not exist." 
        Write-Warning "Make sure you have created this printer (see previous tips)!"
        return
    }

    # this is the file the print driver always prints to
    $TempPDF = $printer.PortName

    # is the printer set up correctly and the port name is the output file path?
    if ($TempPDF -notlike '?:\*')
    {
        Write-Warning "Printer $printerName is not set up correctly." 
        Write-Warning "Make sure you have created this printer as instructed (see previous tips)!"
        return
    }

    # make sure old print results are removed
    $exists = Test-Path -Path $TempPDF
    if ($exists) { Remove-Item -Path $TempPDF -Force }

    # send anything that is piped to this function to PDF
    $input | Out-Printer -Name $printerName

    # wait for the print job to be completed, then move file
    $ok = $false
    do { 
        Start-Sleep -Milliseconds 500 
        Write-Host '.' -NoNewline
                
        $fileExists = Test-Path -Path $TempPDF
        if ($fileExists)
        {
            try
            {
                Move-Item -Path $TempPDF -Destination $Path -Force -ea Stop
                $ok = $true
            }
            catch
            {
                # file is still in use, cannot move
                # try again
            }
        }
    } until ( $ok )
    Write-Host

    # open file if requested
    if ($Open)
    {
        Invoke-Item -Path $Path
    }
}

Now it’s trivial to pipe results to a PDF file:

 
PS> Get-Service | Out-PDFFile -Path $home\desktop\services.pdf -Open

PS> Get-ComputerInfo | Out-PDFFile -Path $home\Desktop\computerinfo.pdf -Open
 

Voilá. That was easy!

Note that we deliberately chose to create a “Simple Function”. This way, all piped input is available in the $Input automatic variable. If you start adding attributes to the parameters, i.e. to make the -Path parameter mandatory, you turn the code into an “Advanced Function”, and $input no longer exists. We’ll look into this tomorrow.


psconf.eu – PowerShell Conference EU 2019 – June 4-7, Hannover Germany – visit www.psconf.eu There aren’t too many trainings around for experienced PowerShell scripters where you really still learn something new. But there’s one place you don’t want to miss: PowerShell Conference EU - with 40 renown international speakers including PowerShell team members and MVPs, plus 350 professional and creative PowerShell scripters. Registration is open at www.psconf.eu, and the full 3-track 4-days agenda becomes available soon. Once a year it’s just a smart move to come together, update know-how, learn about security and mitigations, and bring home fresh ideas and authoritative guidance. We’d sure love to see and hear from you!

Twitter This Tip! ReTweet this Tip!

Anonymous