90 lines
3.0 KiB
PowerShell
90 lines
3.0 KiB
PowerShell
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$SourceFolder
|
|
)
|
|
|
|
function Get-MediaCreationDate {
|
|
param([string]$FilePath)
|
|
|
|
# Try extracting date from filename (YY-MM-DD HH-MM-SS format)
|
|
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)
|
|
$filenameRegex = '^(\d{2})-(\d{2})-(\d{2})\s(\d{2})-(\d{2})-(\d{2})'
|
|
|
|
if ($fileName -match $filenameRegex) {
|
|
try {
|
|
$year = "20" + $matches[1]
|
|
$month = $matches[2]
|
|
$day = $matches[3]
|
|
$hour = $matches[4]
|
|
$minute = $matches[5]
|
|
$second = $matches[6]
|
|
|
|
return [datetime]::ParseExact("${year}-${month}-${day} ${hour}:${minute}:${second}", "yyyy-MM-dd HH:mm:ss", $null)
|
|
}
|
|
catch {}
|
|
}
|
|
|
|
# Try Windows Shell metadata
|
|
try {
|
|
Add-Type -AssemblyName "System.Windows.Forms"
|
|
$shell = New-Object -ComObject Shell.Application
|
|
$folder = $shell.Namespace((Get-Item $FilePath).DirectoryName)
|
|
$fileItem = $folder.ParseName((Get-Item $FilePath).Name)
|
|
$dateTaken = $folder.GetDetailsOf($fileItem, 4)
|
|
|
|
if ($dateTaken) {
|
|
return [datetime]::Parse($dateTaken)
|
|
}
|
|
}
|
|
catch {}
|
|
|
|
# Fallback to file creation time
|
|
return (Get-Item $FilePath).CreationTime
|
|
}
|
|
|
|
# Media file extensions to process
|
|
$mediaExtensions = @('.mp4', '.avi', '.mov', '.mkv', '.wmv', '.jpg', '.jpeg', '.png', '.gif', '.heic')
|
|
|
|
# Get all media files recursively
|
|
$mediaFiles = Get-ChildItem -Path $SourceFolder -Recurse -File |
|
|
Where-Object { $mediaExtensions -contains $_.Extension.ToLower() }
|
|
|
|
foreach ($file in $mediaFiles) {
|
|
try {
|
|
# Get creation date
|
|
$creationDate = Get-MediaCreationDate -FilePath $file.FullName
|
|
|
|
# Create target directory structure
|
|
$targetYear = $creationDate.ToString("yyyy")
|
|
$targetMonth = $creationDate.ToString("MM")
|
|
$newFileName = $creationDate.ToString("yyyyMMdd_HHmmss") + $file.Extension
|
|
|
|
$targetFolder = Join-Path -Path $SourceFolder -ChildPath "$targetYear\$targetMonth"
|
|
|
|
# Create target directory if it doesn't exist
|
|
if (-not (Test-Path -Path $targetFolder)) {
|
|
New-Item -ItemType Directory -Path $targetFolder | Out-Null
|
|
}
|
|
|
|
# Full path for new file
|
|
$newFilePath = Join-Path -Path $targetFolder -ChildPath $newFileName
|
|
|
|
# Avoid overwriting existing files
|
|
$counter = 1
|
|
while (Test-Path -Path $newFilePath) {
|
|
$newFileName = $creationDate.ToString("yyyyMMdd_HHmmss") + "_$counter" + $file.Extension
|
|
$newFilePath = Join-Path -Path $targetFolder -ChildPath $newFileName
|
|
$counter++
|
|
}
|
|
|
|
# Move and rename file
|
|
Move-Item -Path $file.FullName -Destination $newFilePath -ErrorAction Stop
|
|
|
|
Write-Host "Processed: $($file.Name) -> $newFilePath"
|
|
}
|
|
catch {
|
|
Write-Warning "Failed to process $($file.Name): $_"
|
|
}
|
|
}
|
|
|
|
Write-Host "Media file renaming complete." |