Skip to content

Instantly share code, notes, and snippets.

@obsti8383
Created September 3, 2022 18:43
Show Gist options
  • Save obsti8383/bcc67098bdc6fca65b05720da8b20d84 to your computer and use it in GitHub Desktop.
Save obsti8383/bcc67098bdc6fca65b05720da8b20d84 to your computer and use it in GitHub Desktop.
renamePictures PowerShell Script using exiftool
# Example calls:
# ./renamePictures.ps1
# ./renamePictures.ps1 -defaultDescription Holland2022
# ./renamePictures.ps1 -fixedDescription Hallo123
# ./renamePictures.ps1 -folder hallo\. -defaultDescription Holland2022
param(
[string]$folder=".",
[switch]$simulate,
[switch]$removeExistingDates,
[switch]$dontUseDescription,
[string]$defaultDescription,
[string]$fixedDescription
)
## needs exiftool! ##
# Windows: winget install exiftool
# Linux SUSE: sudo zypper in exiftool
# Linux APT: sudo apt-get install exiftool
$ErrorActionPreference = "Stop"
$picFilter = 'JPG|GIF|PNG|JPEG'
function renameRecursively {
param (
[System.IO.FileSystemInfo]$file,
[string]$newName,
[int]$counter
)
if ( $counter -ne 0 ){
$destName = $newName + "_" + $counter + $file.Extension
} else {
$destName = $newName + $file.Extension
}
if ($destName -eq $file.FullName){
# nothing to do, file already has correct name
Write-Host "Nothing to do" #$destName -ForegroundColor Green
return
}
if (-not(Test-Path -Path $destName)) {
Write-Host $destName -ForegroundColor Cyan
Move-Item $file.FullName $destName
} else {
$counter++
renameRecursively -file $file -newName $newName -counter $counter
}
}
function getExifTool(){
if($IsLinux){
# assume exiftool is in path in Linux OS
return "exiftool"
}
# first check if exiftool.exe is in same directory as this script
$exiftool = $PSScriptRoot+"\exiftool.exe"
if (Test-Path -Path $exiftool){
return $exiftool
}
# Then check for %LocalAppData%\Programs\ExifTool
$exiftool = $Env:LocalAppData+"\Programs\ExifTool\ExifTool.exe"
if (Test-Path -Path $exiftool){
return $exiftool
}
Write-Host "Searching for exiftool binary on %LocalAppData%. This might take a while..."
$exiftools = Get-Childitem -Path $Env:LocalAppData\ -Include exiftool.exe -Force -Recurse -File -ErrorAction SilentlyContinue
# just use the first one
if ($exiftools -ne $null -and $exiftools[0] -ne $null){
Write-Host "Found "+$exiftools[0].FullName
return $exiftools[0].FullName
}
Write-Host "Searching for exiftool binary on C:\. This might take a while..."
$exiftools = Get-Childitem -Path C:\ -Include exiftool.exe -Force -Recurse -File -ErrorAction SilentlyContinue
# just use the first one
if ($exiftools -ne $null -and $exiftools[0] -ne $null){
Write-Host "Found "+$exiftools[0].FullName
return $exiftools[0].FullName
} else {
Write-Host "No exiftool.exe found, aborting..."
exit 1
}
}
$exiftool = getExifTool
Write-Host "Using exiftool binary: " + $exiftool
# check input parameters
if($dontUseDescription -eq $false -and $defaultDescription -eq ""){
$defaultDescription = Read-Host "Please enter default description for filename > "
#Write-Host "Error: Please always use '-defaultDescription' when using descriptions in filenames. Otherwise use '-dontUseDescription'"
#exit 1
}
# get all files, filtered by the common picture types
$files = Get-ChildItem $folder -File | Where-Object { $_.Extension -match $picFilter }
ForEach ($file in $files) {
Write-Host $file.FullName "`t->`t" -ForegroundColor Cyan -NoNewLine
# get DateTimeOriginal from EXIF data
$takenData = (& $exiftool -ignoreMinorErrors -DateTimeOriginal -s -s -s $file.FullName)
try {
$date = [DateTime]::ParseExact($takenData, 'yyyy:MM:dd HH:mm:ss', $null)
}
catch {
# ignore error, do nothing
}
if ($null -eq $date) {
Write-Host 'Error: No ''Date Taken'' in Exif' -ForegroundColor Cyan
}
else {
$newname = $file.BaseName
if ("" -ne $fixedDescription) {
# set new file name with fixed description
$newname = $fixedDescription
}
if (-not($dontUseDescription)) {
# set new file name with description from metadata
$description = (& $exiftool -ignoreMinorErrors -ImageDescription -s -s -s $file.FullName)
if ($null -eq $description -or "" -eq $description ) {
$description = (& $exiftool -ignoreMinorErrors -xmp:description -s -s -s $file.FullName)
if ($null -eq $description -or "" -eq $description ) {
$description = $defaultDescription
}
}
$newname = $description
$newname = $newname -replace '[^a-zA-Z0-9_\.]', '' # remove all non wanted special characters
}
if ($removeExistingDates) {
# remove existing numbers and underscores that are 6 chars or longer
$newname = $newname -replace '[0-9_-]{6,}', ''
}
# add date+time in front of new name
$newName = $date.ToString('yyyyMMdd_HHmmss_') + $newname
# create full path (incl. directory name)
$newName = (Join-Path $file.DirectoryName $newName)
if ( $false -eq $simulate ) {
renameRecursively -file $file -newname $newName
} else {
# only output filename in case of simulation
# important: does not consider filename conflicts
$destName = $newName + $file.Extension
Write-Host $destName -ForegroundColor Cyan
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment