PowerShell print all pdf's in a folder cleanly

Viewed 840

Goal: A module that will Print All PDF files within a folder to a user selected printer using PowerShell

The Question: Is there is cleaner way to print 100s of PDF files without calling acrobat directly?

The Current Approach: (Scroll down for the full function)

Start-Process -FilePath $obj.FilePath -Verb PrintTo $obj.PrinterName

There is typically 500 files or more that need to print. Using the current method the PC needs to:

  • Open Acrobat
  • Issue the print
  • Wait for adobe to send to printer

This can be really slow, sometimes adobe crashes and the files that were issued to print just get terminated. I thought i could use Start-Job | Wait-Job | Receive-Job to monitor the status and confirm the job was completed but it turns out once the command is sent to adobe the Job is considered done and brings us back to the potential for adobe to crash and the papers not getting printed. I also tried to issue a -Passthru or -Wait to monitor the process on the Start-Process command, no luck there, back to the above issue.

Don't get me wrong the below is functional but not practical and has a lot of shortfalls.

Notes:

  • select the printer Get-Printer | Out-GridView -OutputMode Single |
  • It is piped to a ForEach-Object, this is due to the potential to use -OutputMode Multiple
  • This script has minor optimizations for Write-Progress
  • The end Module will allow a list of file paths to be Piped to the function Called using: PrintFilesInFolder -pathToFiles "\\path\to\files\" -fileTypeToProcess "*.pdf"
Function PrintFilesInFolder
{
    Param
    (
        [Parameter(Mandatory=$true)]
        [String[]] $pathToFiles,
        [Parameter(Mandatory=$true)]
        [String] $fileTypeToProcess
    )
    Get-Printer | Out-GridView -OutputMode Single | 
    ForEach-Object {
        $printname = $_.Name
        $files = Get-ChildItem "$pathToFiles$fileTypeToProcess"
        $NumberOfFiles = $files.Length
        $interval = $NumberOfFiles / 100
        $count = 0
        
            $files | ForEach-Object {
                $percent = $count * 100 / $files.Length
                $obj = New-Object PSObject
                $obj | Add-Member -MemberType NoteProperty -Name “FilePath” -Value $_.FullName
                $obj | Add-Member -MemberType NoteProperty -Name “PrinterName” -Value $printname

                $job = Start-Job {
                    param(
                        $obj
                    )
                    Start-Process -FilePath $obj.FilePath -Verb PrintTo $obj.PrinterName
                } -ArgumentList $obj | Wait-Job
                
            
                if(($count % $interval -eq 0) -or ($count -le 10)){
                    Write-Progress -Activity "Processing $count of $NumberOfFiles" -Status "Processing $_" -PercentComplete $percent
                }
                $count += 1
            }
    }

}
0 Answers
Related