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
Please also mark the comments that contributed to the solution of the article
Content-Key: 4081194118
Url: https://administrator.de/contentid/4081194118
Printed on: May 28, 2023 at 03:05 o'clock
2 Comments
Latest comment
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{
# 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()}
}
}
}
}
}
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