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
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 4081194118
Url: https://administrator.de/contentid/4081194118
Ausgedruckt am: 21.11.2024 um 17:11 Uhr
5 Kommentare
Neuester Kommentar
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:
Grüße Uwe
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:
Get-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{
$finfo = Get-Item -LiteralPath $file
# get pdf reader
$reader = New-Object iTextSharp.text.pdf.PdfReader $file
# create temporary file to store changes into
$tmp = join-path $finfo.DirectoryName ([IO.Path]::GetRandomFileName())
# handle case where file with random file already esists, and generate new name until free
while(Test-Path -LiteralPath $tmp -PathType Leaf){
$tmp = join-path $finfo.DirectoryName ([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()
# set original time stamps to file
Get-Item -LiteralPath $tmp | %{
$_.LastWriteTime = $finfo.LastWriteTime
$_.CreationTime = $finfo.CreationTime
}
# remove original file
remove-item $file -Force
# rename temp file back to original name
Rename-Item -LiteralPath $tmp -NewName $finfo.Name -Force
}catch{
write-host $_.Exception.Message -F Red
}finally{
if($reader){$reader.Dispose()}
if($fs){$fs.Dispose()}
if($stamper){$stamper.Dispose()}
}
}
}
}
}
Nutzungsbeispiele 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
Hallo colinardo ,
ich habe dein Script hier verwendet und es arbeitet wunderbar
ich habe nur eine Frage an Dich, da ich in Powershell nicht so bewandert bin.
Wenn ich mit
die Metadaten einer Datei verändere (z.B. Author/Titel) dann klappt das super.
Jedoch werden aber auch das Erstelldatum und das Änderungsdatum auf das aktuelle Datum gesetzt.
Dieses würde ich aber gerne unverändert lassen, so das wirklich nur die genannten Metadaten geändert werden - Das Erstell- und Änderungsdatum soll aber nicht geändert werden.
Kannst Du mir sagen bzw. helfen wie ich das im oben genannten Powershell ändern muss.
Danke schon mal für Deine Antwort und Hilfe.
Viele Grüße
Andreas
ich habe dein Script hier verwendet und es arbeitet wunderbar
#edit# hier mal zwei Funktionen mit Beispielen am Ende die ich dafür nutze:
Get-PDFMetaData / Set-PDFMetaData
ich habe nur eine Frage an Dich, da ich in Powershell nicht so bewandert bin.
Wenn ich mit
Get-ChildItem -LiteralPath 'D:\quelle' -File -Filter *.pdf | Set-PDFMetaData -metadata @{Author="Max Muster";Title="Another Title"}
die Metadaten einer Datei verändere (z.B. Author/Titel) dann klappt das super.
Jedoch werden aber auch das Erstelldatum und das Änderungsdatum auf das aktuelle Datum gesetzt.
Dieses würde ich aber gerne unverändert lassen, so das wirklich nur die genannten Metadaten geändert werden - Das Erstell- und Änderungsdatum soll aber nicht geändert werden.
Kannst Du mir sagen bzw. helfen wie ich das im oben genannten Powershell ändern muss.
Danke schon mal für Deine Antwort und Hilfe.
Viele Grüße
Andreas