Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $InputDir = "C:\PDF\IN" $ExportDir = "C:\PDF\OUT" $ErrorDir = "C:\PDF\ERROR" $TempDir = "C:\PDF\TEMP" $WatermarkPdf = "C:\PDF\briefpapier.pdf" # MUSS 2 Seiten haben (1+2) $ITextDllDir = "C:\Tools\itext_bundle\publish" $WorkerScript = "C:\PDF\pdf_worker.ps1" $DeleteOriginalAfterSuccess = $true $AddDebugMarker = $true # setzt klein "WM1"/"WM2" ins PDF, damit du es siehst function Initialize-Directories { foreach ($d in @($InputDir, $ExportDir, $ErrorDir, $TempDir)) { if (-not (Test-Path $d)) { New-Item -ItemType Directory -Path $d | Out-Null } } } function New-SafeOutputName { param([Parameter(Mandatory)] [string] $InputPath, [Parameter(Mandatory)] [string] $OutDir) $base = [IO.Path]::GetFileNameWithoutExtension($InputPath) $ext = [IO.Path]::GetExtension($InputPath) $out = Join-Path $OutDir ($base + $ext) if (-not (Test-Path $out)) { return $out } $ts = Get-Date -Format "yyyyMMdd_HHmmss_fff" return Join-Path $OutDir ("{0}_{1}{2}" -f $base, $ts, $ext) } function Quote-Arg([string]$s) { if ($null -eq $s) { return '""' } '"' + ($s -replace '"','\"') + '"' } Initialize-Directories if (-not (Test-Path $WorkerScript)) { throw "Worker-Script fehlt: $WorkerScript" } if (-not (Test-Path $WatermarkPdf)) { throw "Wasserzeichen-Datei fehlt: $WatermarkPdf" } if (-not (Test-Path $ITextDllDir)) { throw "ITextDllDir fehlt: $ITextDllDir" } $runLog = Join-Path $ErrorDir ("run_{0}.log" -f (Get-Date -Format "yyyyMMdd_HHmmss")) # Logfile garantiert anlegen, damit “keine Log-Datei” ausgeschlossen ist [System.IO.File]::WriteAllText($runLog, ("[{0}] RUN START`r`n" -f (Get-Date))) $files = @(Get-ChildItem -LiteralPath $InputDir -Filter "*.pdf" -File -Force | Sort-Object LastWriteTime) if ($files.Count -eq 0) { Write-Host "Keine PDFs gefunden in: $InputDir" Write-Host "Log: $runLog" exit 0 } Write-Host ("Gefunden: {0} PDF(s)" -f $files.Count) Write-Host "Log: $runLog" foreach ($file in $files) { $tempOut = New-SafeOutputName -InputPath $file.FullName -OutDir $TempDir $finalOut = New-SafeOutputName -InputPath $file.FullName -OutDir $ExportDir Write-Host ("Worker startet: {0}" -f $file.Name) # WICHTIG: Argumente als EIN String mit sicherem Quoting -> keine Param-Zerlegung bei Leerzeichen $argString = @( "-NoProfile", "-ExecutionPolicy Bypass", "-File", (Quote-Arg $WorkerScript), "-InputPdf", (Quote-Arg $file.FullName), "-OutputPdf", (Quote-Arg $tempOut), "-WatermarkPdf", (Quote-Arg $WatermarkPdf), "-ITextDllDir", (Quote-Arg $ITextDllDir), "-LogFile", (Quote-Arg $runLog), "-AddDebugMarker", (Quote-Arg ($AddDebugMarker.ToString())) ) -join " " $p = Start-Process -FilePath "pwsh.exe" -ArgumentList $argString -Wait -PassThru -WindowStyle Hidden if ($p.ExitCode -eq 0 -and (Test-Path $tempOut)) { Move-Item -LiteralPath $tempOut -Destination $finalOut -Force if ($DeleteOriginalAfterSuccess) { Remove-Item -LiteralPath $file.FullName -Force } Write-Host ("OK: {0}" -f $file.Name) } else { if (Test-Path $tempOut) { Remove-Item -LiteralPath $tempOut -Force -ErrorAction SilentlyContinue } $errDest = New-SafeOutputName -InputPath $file.FullName -OutDir $ErrorDir try { Move-Item -LiteralPath $file.FullName -Destination $errDest -Force } catch {} Write-Host ("FAIL (ExitCode {0}): {1}" -f $p.ExitCode, $file.Name) } } Write-Host "Fertig." Write-Host "Log: $runLog"