Hi Nextcloud Community,
I created a simple PowerShell script that automatically sets the creation, modification, and last access dates of photos from their EXIF metadata.
It works with JPG, JPEG, PNG, TIF, TIFF, no external tools needed.
Key features:
- Batch process entire folders.
- Manual folder path entry.
- No ExifTool required.
- Runs on Windows PowerShell 5.1. (Windows default)
<#
.SYNOPSIS
Updates the creation, modification, and last access dates of photo files
from their original EXIF date ("DateTimeOriginal" or "DateTaken") without using ExifTool.
.DESCRIPTION
This PowerShell script reads EXIF metadata directly using .NET (System.Drawing)
to extract the capture date, then applies that date to the file attributes.
Supports JPG, JPEG, PNG, TIF, and TIFF formats.
.AUTHOR
DX90
.REQUIREMENTS
- PowerShell 5.1 or higher
- .NET System.Drawing library available (default on Windows)
#>
# -------------------------------
# Main Script
# -------------------------------
Add-Type -AssemblyName System.Drawing
# Request the path
$Path = Read-Host "đź“‚ Enter the full path of the folder containing the photos"
if (-not (Test-Path $Path)) {
Write-Host "❌ The path '$Path' was not found."
exit
}
# Include subfolders?
$RecurseInput = Read-Host "Include subfolders? (y/n)"
if ($RecurseInput -eq "y" -or $RecurseInput -eq "Y") {
$Recurse = $true
} else {
$Recurse = $false
}
# Extensions to search for
$extensions = ".jpg", ".jpeg", ".png", ".tif", ".tiff"
Write-Host "`n🔍 Searching for files in $Path..."
# Get files ignoring case
$files = Get-ChildItem -Path $Path -Recurse:$Recurse -File | Where-Object { $extensions -contains $_.Extension.ToLower() }
if ($files.Count -eq 0) {
Write-Host "⚠️ No photo files found in this folder."
exit
}
foreach ($file in $files) {
try {
# Read the image to get EXIF date
$image = [System.Drawing.Image]::FromFile($file.FullName)
$propItem = $image.GetPropertyItem(36867) # DateTimeOriginal
if ($propItem) {
$dateString = [System.Text.Encoding]::ASCII.GetString($propItem.Value).Trim()
$dateString = $dateString -replace "\0",""
$dateTaken = [datetime]::ParseExact($dateString, "yyyy:MM:dd HH:mm:ss", $null)
# Release the image
$image.Dispose()
# Apply dates
Set-ItemProperty -LiteralPath $file.FullName -Name CreationTime -Value $dateTaken
Set-ItemProperty -LiteralPath $file.FullName -Name LastWriteTime -Value $dateTaken
Set-ItemProperty -LiteralPath $file.FullName -Name LastAccessTime -Value $dateTaken
Write-Host "✅ $($file.Name) → date updated: $dateTaken"
} else {
$image.Dispose()
Write-Host "⚠️ No EXIF date for: $($file.Name)"
}
}
catch {
Write-Host "❌ Error with $($file.Name): $_"
}
}
Write-Host "`nâś… Script completed."
pause
And french version :
<#
.SYNOPSIS
Met à jour les dates de création, de modification et de dernier accès des fichiers photo
Ă partir de la date EXIF originale ("DateTimeOriginal" ou "DateTaken") sans utiliser ExifTool.
.DESCRIPTION
Ce script PowerShell lit les métadonnées EXIF directement à l’aide de .NET (System.Drawing)
pour extraire la date de prise de vue, puis applique cette date aux attributs du fichier.
Compatible avec les formats JPG, JPEG, PNG, TIF et TIFF.
.AUTEUR
DX90
.PRÉREQUIS
- PowerShell 5.1 ou supérieur
- Bibliothèque .NET System.Drawing disponible (par défaut sur Windows)
#>
# -------------------------------
# Script principal
# -------------------------------
Add-Type -AssemblyName System.Drawing
# Demande du chemin
$Path = Read-Host "đź“‚ Entrez le chemin complet du dossier contenant les photos"
if (-not (Test-Path $Path)) {
Write-Host "❌ Le chemin '$Path' est introuvable."
exit
}
# Inclure les sous-dossiers ?
$RecurseInput = Read-Host "Inclure les sous-dossiers ? (o/n)"
if ($RecurseInput -eq "o" -or $RecurseInput -eq "O") {
$Recurse = $true
} else {
$Recurse = $false
}
# Extensions recherchées
$extensions = ".jpg", ".jpeg", ".png", ".tif", ".tiff"
Write-Host "`n🔍 Recherche des fichiers dans $Path..."
# Récupération des fichiers sans problème de casse
$files = Get-ChildItem -Path $Path -Recurse:$Recurse -File | Where-Object { $extensions -contains $_.Extension.ToLower() }
if ($files.Count -eq 0) {
Write-Host "⚠️ Aucun fichier photo trouvé dans ce dossier."
exit
}
foreach ($file in $files) {
try {
# Lire l'image pour obtenir la date EXIF
$image = [System.Drawing.Image]::FromFile($file.FullName)
$propItem = $image.GetPropertyItem(36867) # DateTimeOriginal
if ($propItem) {
$dateString = [System.Text.Encoding]::ASCII.GetString($propItem.Value).Trim()
$dateString = $dateString -replace "\0",""
$dateTaken = [datetime]::ParseExact($dateString, "yyyy:MM:dd HH:mm:ss", $null)
# Libérer l'image
$image.Dispose()
# Appliquer les dates
Set-ItemProperty -LiteralPath $file.FullName -Name CreationTime -Value $dateTaken
Set-ItemProperty -LiteralPath $file.FullName -Name LastWriteTime -Value $dateTaken
Set-ItemProperty -LiteralPath $file.FullName -Name LastAccessTime -Value $dateTaken
Write-Host "✅ $($file.Name) → date mise à jour : $dateTaken"
} else {
$image.Dispose()
Write-Host "⚠️ Pas de date EXIF pour : $($file.Name)"
}
}
catch {
Write-Host "❌ Erreur avec $($file.Name) : $_"
}
}
Write-Host "`n✅ Script terminé."
pause
To conserve icons in script, you must save and use UTF8 BOM
Perfect for keeping photo timestamps correct afer downloading from Nextcloud.
I’d like to hear your thoughts, feedback, or suggestions for improving this tool.
Thank’s