Out-PDFFile.ps1
function Out-PDFFile { <# .SYNOPSIS Prints data to a PDF file using the PrintToPDF printer driver .DESCRIPTION Prints data to a printer called "PrintPDFUnattended" which prints the data to a static file in the temp folder without user interaction. The generated PDF file is then moved to a user-specified location. If the printer "PrintPDFUnattended" is not present, the function calls the dependent function Install-PDFPrinter. Requires Windows 10, Server 2016, or better. .PARAMETER Path Path to PDF file that is generated .PARAMETER Open When specified, the generated PDF file is opened in the associated PDF viewer (if one is available) .EXAMPLE Get-Process | Out-PDFFile -Path $home\Desktop\doc.pdf -Open Saves a process list to a PDF file called doc.pdf on the user desktop, and opens the file in the associated PDF viewer. .NOTES This function requires the function Install-PDFPrinter #> 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 } } |