kreuzberger
Goto Top

PDF Eigenschaften mit PowerShell bearbeiten

Moin ihr Digitalfreunde,

kennt jemand zufällig eine Lösung, ob bzw. wie man per Powershell (Nachladbares Modul?) die Tags einer PDF auslesen und bearbeiten könnte?

In einer PDF stehen ja „Tags“ wie zb. >Titel<, >Verfasser<, >Thema< und >Stichworte<.

Ich würde gerne nach diesen Tags suchen können per PowerShell und ggf. Änderungen vornehmen wollen.

Hat da jemand eine Idee?


Danke im Voraus


Kreuzberger

Content-Key: 4081194118

Url: https://administrator.de/contentid/4081194118

Ausgedruckt am: 26.04.2024 um 15:04 Uhr

Mitglied: StefanKittel
StefanKittel 27.09.2022 um 22:13:12 Uhr
Goto Top
Hallo,
schau mal nach dem PDF Toolkit
https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/
Stefan
Mitglied: colinardo
Lösung colinardo 28.09.2022 aktualisiert um 16:57:13 Uhr
Goto Top
Servus.
Ich mache das immer mit der .NET Bibliothek iTextSharp die sich nativ via Add-Type in die Powershell einbinden lässt. Findest du in meinen Beiträgen/Kommentaren übrigens diverse Beispiele dazu.

#edit# hier mal zwei Funktionen mit Beispielen am Ende die ich dafür nutze:

back-to-topGet-PDFMetaData / Set-PDFMetaData

<#
.Synopsis
    Get PDF Metadata
.DESCRIPTION
    Get PDF Metadata Properties
.EXAMPLE
    Get-PDFMetaData -FilePath "D:\test.pdf"  
.EXAMPLE
    Get-ChildItem -Path "D:\FolderA" -File -Filter *.pdf | Get-PDFMetaData  

    You can use the pipeline to get the metadata from your pdf files
.OUTPUTS
   [System.Collections.Generic.Dictionary[string,string]]
#>
function Get-PDFMetaData {
    [cmdletbinding(SupportsShouldProcess=$true)]
    param(
        # FilePath of PDF
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][Alias('Fullname')][string[]]$FilePath  
    )
    begin{
        # Funktion zum Laden des iTextSharp Assemblies
        function Load-iTextLibrary {
            if($psscriptroot -ne ''){  
                $localpath = join-path $psscriptroot 'itextsharp.dll'  
            }else{
                $localpath = join-path $env:TEMP 'itextsharp.dll'  
            }
            $zip = $null;$tmp = ''  
            try{
                if(!(Test-Path $localpath)){
                    Add-Type -A System.IO.Compression.FileSystem
                    $tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"  
                    write-host "Downloading and extracting required 'iTextSharp.dll' ... " -F Green -NoNewline  

                    (New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/api/v2/package/iTextSharp/5.5.13.1', $tmp)  
                    $zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
                    $zip.Entries | ?{$_.Fullname -eq 'lib/itextsharp.dll'} | %{  
                        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
                    }
                    write-host "OK" -F Green   
                }
                if (Get-Item $localpath -Stream zone.identifier -ea SilentlyContinue){
                    Unblock-File -Path $localpath
                }
                Add-Type -Path $localpath
            }catch{
                throw "Error: $($_.Exception.Message)"  
            }finally{
                if ($zip){$zip.Dispose()}
                if ($tmp -ne ''){del $tmp -Force -EA SilentlyContinue}  
            }
        }
        # iText Library laden
        Load-iTextLibrary
    }
    process{
        foreach($file in $filepath){
            if ($PSCmdlet.ShouldProcess($file,"GetMetadata")){  
                # create reader object
                $reader = New-Object iTextSharp.text.pdf.PdfReader $file
                # output metadata
                $reader.Info
                # cleanup
                $reader.Dispose()
            }
        }
    }
}

<#
.Synopsis
    Set PDF Metadata
.DESCRIPTION
    Write Metadata of PDF files
.EXAMPLE
    Set-PDFMetaData -FilePath "D:\test.pdf" -metadata @{'Author'='Mickey Mouse'}  

    Set the Author-Field from the pdf to a new value
.EXAMPLE
    Get-ChildItem -Path "D:\FolderA" -File -Filter *.pdf | Set-PDFMetaData -metadata @{'Author'='Mickey Mouse'}  

    You can use the pipeline to set the metadata of your pdf files
.OUTPUTS
   [System.Collections.Generic.Dictionary[string,string]]
#>
function Set-PDFMetaData {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][Alias('Fullname')][string[]]$FilePath,  
        [Parameter(mandatory=$true)][ValidateNotNullOrEmpty()][hashtable]$metadata
    )
    begin{
        # Funktion zum Laden des iTextSharp Assemblies
        function Load-iTextLibrary {
            if($psscriptroot -ne ''){  
                $localpath = join-path $psscriptroot 'itextsharp.dll'  
            }else{
                $localpath = join-path $env:TEMP 'itextsharp.dll'  
            }
            $zip = $null;$tmp = ''  
            try{
                if(!(Test-Path $localpath)){
                    Add-Type -A System.IO.Compression.FileSystem
                    $tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"  
                    write-host "Downloading and extracting required 'iTextSharp.dll' ... " -F Green -NoNewline  

                    (New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/api/v2/package/iTextSharp/5.5.13.1', $tmp)  
                    $zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
                    $zip.Entries | ?{$_.Fullname -eq 'lib/itextsharp.dll'} | %{  
                        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
                    }
                    write-host "OK" -F Green   
                }
                if (Get-Item $localpath -Stream zone.identifier -ea SilentlyContinue){
                    Unblock-File -Path $localpath
                }
                Add-Type -Path $localpath
            }catch{
                throw "Error: $($_.Exception.Message)"  
            }finally{
                if ($zip){$zip.Dispose()}
                if ($tmp -ne ''){del $tmp -Force -EA SilentlyContinue}  
            }
        }
        # iText Library laden
        Load-iTextLibrary
    }
    process{
        foreach($file in $filepath){
            if ($PSCmdlet.ShouldProcess($file,"SetMetadata")){  
                $reader = $null; $fs = $null;$stamper = $null
                try{
                    # get pdf reader
                    $reader = New-Object iTextSharp.text.pdf.PdfReader $file
                    # create temporary file to store changes into
                    $tmp = join-path ([IO.Path]::GetDirectoryName($file)) ([IO.Path]::GetRandomFileName())
                    # handle case where file with random file already esists, and generate new name until free
                    while(Test-Path $tmp){
                        $tmp = join-path ([IO.Path]::GetDirectoryName($file)) ([IO.Path]::GetRandomFileName())
                    }
                    # create filestream to temp file
                    $fs = [System.IO.FileStream]::new($tmp,[System.IO.FileMode]::Create,[System.IO.FileAccess]::ReadWrite)
                    # create pdf stamper object with file stream as output
                    $stamper = New-Object iTextSharp.text.pdf.PdfStamper $reader,$fs
                    # get metadata
                    $meta = $reader.Info
                    # set metadata from users hashtable
                    $metadata.GetEnumerator() | %{
                        write-verbose "Key '$($_.Key)' set to value '$($_.Value)'."  
                        if ($meta.ContainsKey($_.Key)){
                            $meta[$_.Key] = $_.Value
                        }else{
                            $meta.Add($_.Key,$_.Value)
                        }    
                    }
            
                    # set metadata into stamper
                    $stamper.MoreInfo = $meta
                    # close stamper/reader
                    $stamper.Close()
                    $stamper.Dispose()
                    $reader.Close()
                    $reader.Dispose()
                    # remove original file
                    remove-item $file -Force
                    # move modified Version into original location
                    move-item -LiteralPath $tmp -Destination $file -Force
                }catch{
                    write-host $_.Exception.Message -F Red
                }finally{
                    if($reader){$reader.Dispose()}
                    if($fs){$fs.Dispose()}
                    if($stamper){$stamper.Dispose()}
                }
            }
        }
    }
}

back-to-topNutzungsbeispiele der beiden Funktionen

# PDF Metadaten auslesen
Get-ChildItem -LiteralPath 'D:\quelle' -File -Filter *.pdf | Get-PDFMetaData  
# PDF Metadaten beschreiben
Get-ChildItem -LiteralPath 'D:\quelle' -File -Filter *.pdf | Set-PDFMetaData -metadata @{Author="Max Muster";Title="Another Title"}  
# Nur PDFs mit bestimmten Metadata-Werten verändern
Get-ChildItem -LiteralPath 'D:\quelle' -File -Filter *.pdf | ?{(Get-PDFMetadata -FilePath $_.Fullname)['Author'] -eq 'Max Muster'} | Set-PDFMetaData -metadata @{Author="Mickey Mouse";Title="Another Title";Subject="Another Subject";Keywords="Tag1,Tag2"} -Verbose  


Grüße Uwe