Search code examples
powershellwindows-server-2008-r2ghostscript

PowerShell and GhostScript


I have a batch script that loops over a folder and flattens the PDFs inside it using GhostScript (9.07). I want to convert it to a PowerShell script because it seems to like to crash every once in a while and I'm just tired of debugging batch files.

Anyway, I have a PS script that seems to work, based on it's output in the console, but I don't actually get any files. Manual entry in PS seems to work even less... What am I doing wrong?

Batch Script

@ECHO OFF
::
:: Process all PDFs and flatten them to PDF/A format
:: =====================================================================================
FOR %%F IN ("J:\Finals\*.pdf") DO (
    IF /I %%F NEQ "*Floor Plan*.pdf" (
::      Convert the original PDF to a flattened PDF PDF/A
::      ========================================================================
        "%ProgramFiles%\gs\gs9.07\bin\gswin64.exe" -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="J:\Finals\%%~nF (Final).pdf" "%%F"
::
::      Delete the original PDF file
::      ========================================================================
        DEL "%%F" /F /Q
::
::      Rename the flattened PDF PDF/A to the original PDF's name
::      ========================================================================
        MOVE "J:\Finals\%%~nF (Final).pdf" "%%F"
    )
)
::
:: Move files form the Readdle drive to the Digital Documents drive
:: =====================================================================================
ROBOCOPY J:\Finals\ K:\ *.* /MOV /R:0 /W:0 /MT

PowerShell Script (so far)

$GhostScript = "$env:ProgramFiles\gs\gs9.07\bin\gswin64c.exe"

Get-ChildItem "C:\Test In\*.pdf" | Where {
    $_.BaseName -NotMatch "Floor Plan"
} | ForEach-Object {
    $InputFile = $_.FullName
    $OutputFile = "C:\Test Out\{0} (Final).pdf" -F $_.BaseName

    & "$GhostScript" -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="$OutputFile" "$InputFile"
}

Output of the PowerShell Script

GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Substituting font Times-Italic for TimesNewRomanPS-ItalicMT.
Loading NimbusRomNo9L-ReguItal font from %rom%Resource/Font/NimbusRomNo9L-ReguItal... 4198200 2870566 3665244 2332637 3 done.
Substituting font Courier for CourierNewPSMT.
Loading NimbusMonL-Regu font from %rom%Resource/Font/NimbusMonL-Regu... 3755680 2306439 4089108 2566088 3 done.
Loading NimbusRomNo9L-Regu font from %rom%Resource/Font/NimbusRomNo9L-Regu... 3796376 2391131 4078352 2484871 3 done.
Loading Dingbats font from %rom%Resource/Font/Dingbats... 3917480 2509851 4280192 2689988 3 done.

For anyone who cares this is being tested on a Windows Server 2008 R2 virtual machine. It has 4GB of RAM and 4vCPUs. I've also checked if there was permissions issues with the test folders I was using and it wasn't the case.

UPDATE

I've updated my post to show what the current script looks like. Surrounding the $OutputFile variable in quotes doesn't do anything. Regardless of quotes or not, I always get output (which I've added above) that indicates the GhostScript is doing what it's supposed to, but ultimately I get no file created...


Solution

  • Well, I figured out a solution. It involves opting out of using GhostScript for PDFtk. Seriously, I have no idea what GhostScript's deal was, but it just refused to work 100%. It worked like 95%, but the last 5% I really cared about (the outputted file) never happened. Anyway, I instead used PDFtk and it just works, and it also works many times faster than GhostScript for the exact same task. I don't get it...

    Here's what my final PowerShell script looks like:

    $PDFtk = "C:\Program Files (x86)\PDF Labs\PDFtk Server\bin\pdftk.exe"
    
    If (Test-Path $PDFtk) {
        Get-ChildItem "J:\Finals\" | Where-Object {
            $_.Extension -Match "pdf"
        } | ForEach-Object {
            $InputFile = $_.FullName
            $OutputFile = "J:\Finals\{0} (Flattened).pdf" -F $_.BaseName
            $DigitalDocumentsFile = "K:\{0}" -F $_.Name
    
            & $PDFtk $InputFile OUTPUT $OutputFile FLATTEN
    
            If (Test-Path $OutputFile) {
                Remove-Item $InputFile
                Move-Item $OutputFile $DigitalDocumentsFile
            }
        }
    }