Jump to content
Fosco

Skript zum Prüfen und Kopieren von PDF Dateien

Recommended Posts

Hallo Leute,

 

ich hatte das Pech, das eine meiner Festplatten sich verabschiedet hatte, auf der jede Menge PDF-Dateien gespeichert waren.

Diese konnte ich zwar "retten", aber ein ganzer Teil davon ist defekt.

Ein Bekannter hat mir ein Powershell-Skript geschrieben, das die Dateien prüft und automatisch umkopiert.

 

Leider bekomme ich eine Fehlermeldung, die für mich kryptisch ist (ich gebe zu bei Powershell absolut blank zu sein).

 

Das Script liegt in einem Order der beinhaltet die Dateien: pdftester.1 und pdftester.exe (prüft die Dateien). Die PDF-Dateien sind in einem entsprechenden Unterordner.

$Speicherpfad = "N:\CutFolders"

# Der erste Teil des Codes sucht nach den Ordnern mit META-INF oder OEPS im Namen und verschiebt sie in den CutFolders Ordner
$pathU = Get-Location
$Remove = Get-ChildItem -Recurse | ?{ $_.PSIsContainer } #| Select-Object FullName

if (Test-Path -Path "$Speicherpfad") {echo success} else {New-Item -ItemType Directory -Force -Path $Speicherpfad}

foreach ($target in $Remove)
{   
  
    if ($target | Select-String -Pattern META-INF) {Move-Item (get-item $target.PSPath ).parent "$Speicherpfad"}
    if ($target | Select-String -Pattern OEPS) {Move-Item (get-item $target.PSPath ).parent "$Speicherpfad"}
           
       }

# Dieser Teil überprüft die verbliebenen PDFs auf Funktion und entfernt die defekten

$items = Get-ChildItem -Path "$pathU\*.pdf" -Recurse -Force 
$progress = 0

foreach ($item in $items)
{   
   $progress++
    
    echo $items.Count - $progress
    
    $los = & pdfinfo $item 2>&1
    if ($los | Select-String -Pattern Error) {Move-Item $item.PSPath "$Speicherpfad"}
    else {}
        
       }

Der obere Teil hat bei den zerflügten Ebooks einwandfrei funktioniert. Leider bekomme ich bei dem unteren Teil, dem pdftest, eine fehlermeldung:

 

& : The term 'pdfinfo.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was 
included, verify that the path is correct and try again.
At N:\rec\Verloren\Dokumente\pdftester.ps1:31 char:14
+     $los = & pdfinfo $item 2>&1
+              ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (pdfinfo.exe:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
 

 

Ich hoffe das es nur ne kleinigkeit ist und ihr mir vielleicht helfen könnt.

Zugeben, ich hab keinen Nerv einige Tausend per Hand prüfen zu müssen.

 

Vielen Dank im voraus..

Fosco

Share this post


Link to post
Share on other sites

Hallo Fosco,

 

ich habe mir die Mühe gemacht für Dich zu recherchieren. Das Problem das du hast ist, dass dir die "pdfinfo.exe" fehlt. Das ergeht aus der Powershell Meldung. Diese ließt die PDF-Datei aus und wirft im Fehlerfall einen Fehler aus. Dieser wird abgefangen und die Datei verschoben.

 

Die PDFInfo.exe bekommst du hier unter der Rubrik: Download the Xpdf command line tools: Windows 32/64-bit

https://www.xpdfreader.com/download.html

 

Ich habe gerade Lust und Laune gehabt Dir das Skript zu verbessern. Einige unnütze Aufrufe entfernt, Variablennamen treffender benannt und die Lesbarkeit/Interpretierbarkeit deutlich erhöht. Das Skript selber habe ich nicht getestet, sollte aber funktionieren. :-)

 

$PdfInfoToolPath musst du so anpassen, das sie auf die pdfinfo.exe zeigt.

$LocationToAnalyse ist der Pfad der nach den Dateien/Ordnern durchsucht wird. Das Skript muss in diesem Pfad selber liegen oder der Pfad angepasst werden. Das ist übrigens in deinem Ursprungsskript auch so.

 

#requires -Version 3.0

# Initialisiere und bereite die Umgebung vor
[string]$DefectFilesPath = 'N:\CutFolders'
[string]$LocationToAnalyse = (Get-Location).Path
[string]$PdfInfoToolPath = "$env:USERPROFILE\Downloads\xpdf-tools-win-4.02\xpdf-tools-win-4.02\bin64\pdfinfo.exe"

if ((Test-Path -Path $DefectFilesPath) -eq $false) 
{
    New-Item -ItemType Directory -Force -Path $DefectFilesPath
}

# Der erste Teil des Codes sucht nach den Ordnern mit META-INF oder OEPS im Namen und verschiebt sie in den CutFolders Ordner
$FoundFolderList = Get-ChildItem -Path $LocationToAnalyse -Recurse -Directory

foreach ($FolderItem in $FoundFolderList)
{
    If(($FolderItem.Name -like '*META-INF*') -or ($FolderItem.Name -like '*OEPS*'))
    {
        Move-Item -Path $FolderItem.FullName -Destination $DefectFilesPath
    }
}

# Dieser Teil überprüft die verbliebenen PDFs auf Funktion und entfernt die defekten
$FoundPdfList = Get-ChildItem -Path $LocationToAnalyse -Filter *.pdf -Recurse
[int]$i = 0

foreach ($FileItem in $FoundPdfList)
{
    $i++
    Write-Progress -Activity 'Prüfe gefundene PDF-Dateien' -Status "$i von $($FoundFolderList.Count)"
    
    $retValue = Start-Process -FilePath $PdfInfoToolPath -ArgumentList $FileItem -NoNewWindow -PassThru
    
    if ($retValue | Select-String -Pattern Error) 
    {
        Move-Item -Path $FileItem.FullName -Destination $DefectFilesPath
    }
}

 

Edited by MurdocX
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Hallo MurdocX,

 

vielen Dank für deine Hilfe.

Ich komme leider heute nicht mehr dazu, das Script zu testen, werde es aber so schnell wie möglich nachholen.

Dann werde ich mich mit dem Ergebnis melden.

 

Und auch vielen Dank für die weitere Überarbeitung.

 

Fosco

Share this post


Link to post
Share on other sites

Hallo MurdocX,

 

ich habe das Script getestet. Es läuft sauber durch, aber verschiebt leider keine defekten Dateien. In dem Text-File zu pdfinfo.exe habe ich gefunden, das ein nummerischer Exit-Code zurück gegeben wird.

Zitat

0      No error.

1      Error opening a PDF file.

2      Error opening an output file.

3      Error related to PDF permissions.

99     Other error

Wenn ich dein Script richtig verstehe, fragt es keinen nummerischen Code ab, sondern erwartet das "Wort" Error"?

Könnte es daran liegen?

Und wenn ja, kann man das entsprechend abändern (ich denke, das es der Wert 1 sein müsste...)?

 

Nochmals Danke und Gruß

Fosco

Edited by Fosco

Share this post


Link to post
Share on other sites

Hallo Fosco,

 

die Ausgabe ist nicht wie von mir vorher vermutet in der Variable gespeichert, damit kann sie auch nicht ausgewertet werden. Das hab ich wieder zur vorherigen Variante abgeändert. Der Vollständigkeit hab ich es nochmal komplett für Dich gepostet.

 

#requires -Version 3.0

# Initialisiere und bereite die Umgebung vor
[string]$DefectFilesPath = 'N:\CutFolders'
[string]$LocationToAnalyse = (Get-Location).Path
[string]$PdfInfoToolPath = "$env:USERPROFILE\Downloads\xpdf-tools-win-4.02\xpdf-tools-win-4.02\bin64\pdfinfo.exe"

if ((Test-Path -Path $DefectFilesPath) -eq $false) 
{
    New-Item -ItemType Directory -Force -Path $DefectFilesPath
}

# Der erste Teil des Codes sucht nach den Ordnern mit META-INF oder OEPS im Namen und verschiebt sie in den CutFolders Ordner
$FoundFolderList = Get-ChildItem -Path $LocationToAnalyse -Recurse -Directory

foreach ($FolderItem in $FoundFolderList)
{
    If(($FolderItem.Name -like '*META-INF*') -or ($FolderItem.Name -like '*OEPS*'))
    {
        Move-Item -Path $FolderItem.FullName -Destination $DefectFilesPath
    }
}

# Dieser Teil überprüft die verbliebenen PDFs auf Funktion und entfernt die defekten
$FoundPdfList = Get-ChildItem -Path $LocationToAnalyse -Filter *.pdf -Recurse
[int]$i = 0

foreach ($FileItem in $FoundPdfList)
{
    $i++
    Write-Progress -Activity 'Prüfe gefundene PDF-Dateien' -Status "$i von $($FoundFolderList.Count)"
    
    $retValue = & $PdfInfoToolPath $FileItem 2>&1
    
    if ($retValue | Select-String -Pattern Error) 
    {
        Move-Item -Path $FileItem.FullName -Destination $DefectFilesPath
    }
}

 

Share this post


Link to post
Share on other sites

Hmm...

Also ich glaube, wir sind einen Schritt weiter...

Die Dateien werden jetzt umkopiert. Leider werden aber alle Dateien umkopiert, und nicht nur diejenigen die defekt sind.

 

Ich versuche ja zumindest das Script zu verstehen, deshalb frage ich jetzt mal ganz dumm...

Zitat

$retValue = & $PdfInfoToolPath $FileItem 2>&1

 

if ($retValue | Select-String -Pattern Error)

Wird hier wirklich der nummerische Fehlercode abgeprüft?

Mich irritiert das "Select-String -Pattern Error", das für mich aussieht, als wenn nach dem Wort "Error" geprüft werden sollte.

 

Sry, falls es eine dämliche Fragen sein sollte....

 

Edited by Fosco

Share this post


Link to post
Share on other sites

Hallo Fosco,

 

ja genau. So ist es in deinem ursprünglichen Skript drin. Er ließt aus, ob das Programm einen Error bei lesen der PDF ausgibt. Falls ja, also ein Error vorkommt, wird die Datei verschoben. 
 

Kommt denn ein Error beim manuellen auslesen vor?

 

Update:

Ich hab das Skript nun selber ausgeführt und konnte mein Problem erkennen. $FileItem ist ein Objekt und kein String. Daher hat er keinen Pfad gefunden und jede Datei mit ein "Error" versehen. Ersetze den unteren Teil bitte mit dem von mir hier geposteten und teste erneut:

foreach ($FileItem in $FoundPdfList)
{
    $i++
    Write-Progress -Activity 'Prüfe gefundene PDF-Dateien' -Status "$i von $($FoundPdfList.Count)"
    [string]$FilePath = $FileItem.FullName
       
    $retValue = & $PdfInfoToolPath $FilePath 2>&1
    
    if ($retValue | Select-String -Pattern Error) 
    {
        Move-Item -Path $FilePath -Destination $DefectFilesPath
    }
}

Auch ich bin nicht fehlerfrei. Besonders wenn ich es selber nicht teste. Der Code ist nun getestet und für gut befunden. :-)

Edited by MurdocX

Share this post


Link to post
Share on other sites

Hi MurdocX,

bin leider nicht sofort zum testen gekommen. Habs aber nun erledigt.

Leider mit negativem Ergebniss. Es werden noch immer alle Dateien umkopiert.

 

Schlag mich nicht, wenn ich darauf rumreite aber ich versteh es nicht.

Das Programm"pdfinfo" gibt, so wie ich es verstehe, als Exitcode 0,1,2 oder 99 aus.

Warum prüfst du auf "-String - Pattern Error" ab?

 

Allerdings hast du auch schon ne Menge Zeit reingesteckt. Ich möchte nicht unverschämt sein und dir noch mehr Zeit kosten. Daher wäre es vielleicht an der Zeit, hier einen Break zu machen.

 

Ich werden dann wohl doch alles per Hand prüfen.

Jedenfalls danke ich dir sehr für die Mühe, die du dir gemacht hast.....

Share this post


Link to post
Share on other sites
vor 23 Minuten schrieb Fosco:

Das Programm"pdfinfo" gibt, so wie ich es verstehe, als Exitcode 0,1,2 oder 99 aus.

Das eine hat mit dem Anderen nichts zu tun, bzw. indirekt :-)  Ein ExitCode ist etwas anderes wie die normale Ausgabe aus dem Programm. Anscheinend hast du es gar nicht mal selber probiert. ;-) 

 

Normale Ausgabe:

Zitat

Creator:        Adobe LiveCycle Designer ES 10.0
Producer:       Adobe LiveCycle Designer ES 10.0
CreationDate:   Thu Nov  9 09:25:12 2017
ModDate:        Thu Nov 23 13:56:27 2017
Tagged:         yes
Form:           dynamic XFA
Pages:          1
Encrypted:      no
Page size:      612 x 792 pts (letter) (rotated 0 degrees)
File size:      1784503 bytes
Optimized:      yes
PDF version:    1.7

 

Fehlerhafte Ausgabe:

Zitat

Syntax Warning: May not be a PDF file (continuing anyway)
Syntax Error: Couldn't read xref table
Syntax Warning: PDF file is damaged - attempting to reconstruct xref table...
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table

 

Hier ist das einfache Filtern auf "Error" eine einfache Variante.

 

Was kommt denn raus, wenn du mal eins von den PDFs die verschoben werden händisch ausprobierst?

Share this post


Link to post
Share on other sites
vor einer Stunde schrieb MurdocX:

Anscheinend hast du es gar nicht mal selber probiert. ;-) 

Mea Culpa...

Du hast recht, ich habe es nur über das lesen versucht zu verstehen. Und das hat wohl nicht gefunzt,,,,, :engel:

Ich hoffe es gilt wenigstens, das ich es versucht habe..... ;-)

 

Ich habe aber mal rumprobiert und glaube das "problem" erkannt zu haben.

 

Bei der Datei, die ich nicht öffnen kann erhalte ich diese Meldung:

N:\CutFolders>pdfinfo 10019120.pdf
Syntax Error: Couldn't read xref table
Syntax Warning: PDF file is damaged - attempting to reconstruct xref table...
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table

Diese Datei wird definitiv defekt erkannt.

 

Bei eine Datei, die als Defekt aussortiert wurde gab diese Meldung:

N:\CutFolders>pdfinfo 1000729376.pdf
Syntax Error: Couldn't read xref table
Syntax Warning: PDF file is damaged - attempting to reconstruct xref table...
Title:          Microsoft Word - WHFB_Chronicles_4_maket.doc
Author:         Administrator
Creator:        Pscript.dll Version 5.0
Producer:       Acrobat Distiller 5.0 (Windows)
CreationDate:   Tue Dec 30 15:58:23 2003
ModDate:        Tue Dec 30 15:58:23 2003
Tagged:         no
Form:           none
Pages:          44
Encrypted:      no
Page size:      595 x 842 pts (A4) (rotated 0 degrees)
File size:      37588992 bytes
Optimized:      no
PDF version:    1.3

Beim Schließen "will" die Datei gespeichert werden. Das habe ich mal gemacht, und diese Datei nochmal getestet. Ergebnis:

N:\CutFolders>pdfinfo 1000729376.pdf
Title:          Microsoft Word - WHFB_Chronicles_4_maket.doc
Author:         Administrator
Creator:        Pscript.dll Version 5.0
Producer:       Acrobat Distiller 5.0 (Windows)
CreationDate:   Tue Dec 30 12:58:23 2003
ModDate:        Thu Nov 14 15:42:56 2019
Tagged:         no
Form:           none
Pages:          44
Encrypted:      no
Page size:      595 x 842 pts (A4) (rotated 0 degrees)
File size:      37578898 bytes
Optimized:      yes
PDF version:    1.6

 

Scheinbar kann eine PDF-Datei auch defekt geöffnet werden, wenn es den/die/das "xref table" betrifft.

Kann man sowas ausklammern?

 

Share this post


Link to post
Share on other sites
vor 13 Minuten schrieb Fosco:

Ich hoffe es gilt wenigstens, das ich es versucht habe..... ;-)

Ja das tut es. Denn genau das bringt uns einen Schritt weiter.

 

Das würde auch erklären warum wieder fast alles aussortiert wird. Leider gibt es nur "Alles Gut" oder "Fehler", auch in den ExitCodes. Hier können wir also auch nicht ansetzen. Ein Ansatz lässt sich herauslesen, wenn man die Beiden Fehlermeldungen vergleicht. Der Unterschied ist "Couldn't find trailer dictionary".

 

Aussehen würde es dann so:

foreach ($FileItem in $FoundPdfList)
{
	$i++
	Write-Progress -Activity 'Prüfe gefundene PDF-Dateien' -Status "$i von $($FoundPdfList.Count)" -CurrentOperation $FileItem.Name
	[string]$FilePath = $FileItem.FullName
       
	$retValue = & $PdfInfoToolPath $FilePath 2>&1
    
	if ($retValue | Select-String -Pattern 'find trailer dictionary') 
	{
		Move-Item -Path $FilePath -Destination $DefectFilesPath
	}
}

Jetzt bist du wieder dran.

Edited by MurdocX

Share this post


Link to post
Share on other sites

Ich könnt ausflippen, es klappt....

 

Ich habe etwas über 100 Dateien prüfen lassen, und es wurde nur 30 Dateien aussortiert. Alle habe ich per Hand geöffnet, und alle sind defekt.

Die Änderung auf  "Couldn't find trailer dictionary", umgeht das problem mit der "xref" .

 

Das wird mir reichlich Zeit sparen, wenn ich die defekten Dateien gleich aussortieren kann.

Ich kann dir gar nicht genug danken....

Share this post


Link to post
Share on other sites

Ich muss noch einmal was fragen, bzw. um Hilfe bitten.

 

Das Script läuft wunderbar. Leider klemmt pdfinfo manchmal, und schmiert ab.

An und für sich kein Problem, leider will es dann in einer Massagebox einen Buttonklick (Programm schließen), um weiter zu machen.

Kann man soetwas auch ergänzend automatisieren?

 

Nochmals Danke....

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


Werbepartner:



×
×
  • Create New...