In the previous tip we illustrated how you can use the built-in “Microsoft Print to PDF” printer to send PowerShell output to PDF files. However, this printer prompts you for an output file, so it is no good for automation tasks.

To avoid the file prompt, there is a little-known secret: simply assign the printer a port where you use the output file path as port name. Or in other words, run this script to create a new printer that always prints to a file of your choice:

# requires Windows 10 / Windows Server 2016 or better

# choose a name for your new printer
$printerName = 'PrintPDFUnattended'
# choose a default path where the PDF is saved
$PDFFilePath = "$env:temp\PDFResultFile.pdf"
# choose whether you want to print a test page
$TestPage = $true

# see whether the driver exists
$ok = @(Get-PrinterDriver -Name "Microsoft Print to PDF" -ea 0).Count -gt 0
if (!$ok)
{
    Write-Warning "Printer driver 'Microsoft Print to PDF' not available."
    Write-Warning "This driver ships with Windows 10 or Windows Server 2016."
    Write-Warning "If it is still not available, enable the 'Printing-PrintToPDFServices-Features'"
    Write-Warning "Example: Enable-WindowsOptionalFeature -Online -FeatureName Printing-PrintToPDFServices-Features"
    return
}

# check whether port exists
$port = Get-PrinterPort -Name $PDFFilePath -ErrorAction SilentlyContinue
if ($port -eq $null)
{
    # create printer port
    Add-PrinterPort -Name $PDFFilePath 
}

# add printer
Add-Printer -DriverName "Microsoft Print to PDF" -Name $printerName -PortName $PDFFilePath 

# print a test page to the printer
if ($TestPage)
{
    $printerObject = Get-CimInstance Win32_Printer -Filter "name LIKE '$printerName'"
    $null = $printerObject | Invoke-CimMethod -MethodName printtestpage 
    Start-Sleep -Seconds 1
    Invoke-Item -Path $PDFFilePath
}

After the script is executed, you have a brand-new printer called PrintPDFUnattended, and when you print to it, there is no longer a prompt. Instead, the output is always sent to PDFResultFile.pdf in your temp folder.

Here is a chunk of code that illustrates how you can now print PDF files from PowerShell without dialogs:

# specify the path to the file you want to create
# (adjust if you want)
$OutPath = "$home\desktop\result.pdf"

# this is the file the print driver always prints to
$TempPDF = "$env:temp\PDFResultFile.pdf"

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

# send PowerShell results to PDF
Get-Service | Out-Printer -Name "PrintPDFUnattended"

# 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 $OutPath -Force -ErrorAction Stop
            $ok = $true
        }
        catch
        {
            # file is still in use, cannot move
            # try again
        }
    }
} until ( $ok )
Write-Host

# show new PDF file in explorer
explorer "/select,$OutPath"

When you run this code, a new PDF file called result.pdf is created on your desktop. It contains the list of all services. You can pipe whatever results you like to Out-Printer now and create PDF files.


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