function Out-PDFFile
{
param
(
[string]$Path = "$env:temp\results.pdf",
[Switch]
$Open
)
function Install-PDFPrinter
{
<#
.SYNOPSIS
Installs a new Printer called "PrintPDFUnattended" which prints to file
.DESCRIPTION
Uses the built-in "PrintToPDF" printer driver to create a new printer
that prints unattendedly to a fixed file in the temp folder
.EXAMPLE
Install-PDFPrinter
Installs the printer "PrintPDFUnattended". Needs to be run only once.
To remove the printer again, use this command:
Remove-Printer PrintPDFUnattended
.NOTES
Requires the "PrintToPDF" printer driver shipping with Windows 10, Server 2016, or better
.LINK
URLs to related sites
The first link is opened by Get-Help -Online Install-PDFPrinter
#>
$PrinterDefaultName = 'Microsoft Print to PDF'
$printerName = 'PrintPDFUnattended'
# choose a default path where the PDF is saved:
$PDFFilePath = "$env:temp\PDFResultFile.pdf"
# see whether the driver exists
$ok = @(Get-PrinterDriver -Name $PrinterDefaultName -ea 0).Count -gt 0
if (!$ok)
{
Write-Warning -Message "Printer driver 'Microsoft Print to PDF' not available."
Write-Warning -Message 'This driver ships with Windows 10 or Server 2016.'
Write-Warning -Message "If it is still not available, enable the 'Printing-PrintToPDFServices-Features'"
Write-Warning -Message '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 $PrinterDefaultName -Name $printerName -PortName $PDFFilePath
}
# check to see whether the PDF printer was set up correctly
$printerName = 'PrintPDFUnattended'
$printer = Get-Printer -Name $printerName -ErrorAction SilentlyContinue
if (!$?)
{
Install-PDFPrinter
$printer = Get-Printer -Name $printerName -ErrorAction SilentlyContinue
}
# 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 -Message "Printer $printerName is not set up correctly."
Write-Warning -Message '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 -ErrorAction 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
}
}