# Fonction pour récupérer une Array des extensions d'images et vidéos depuis un json function Get-ImageVideoExtensions { param ( [string] $sourceUrl = "https://cdn.jsdelivr.net/gh/jshttp/mime-db@v1.52.0/db.json" ) $jsonData = (Invoke-RestMethod $sourceUrl).PSObject.Properties $extensions = @() foreach ($item in $jsonData) { if ($item.Name -like "image*" -or $item.Name -like "video*") { $extensions += $item.Value.extensions } } $extensions = $extensions | Sort-Object -Unique return $extensions } # Fonction pour décompresser les archives function Decompress-ArchiveIfNeeded { param( [string]$ArchivePath, [string]$ExtractPath ) if (Test-Path $ArchivePath -PathType Leaf) { $tempDir = Join-Path -Path $ExtractPath -ChildPath ([System.IO.Path]::GetRandomFileName()) while (Test-Path $tempDir) { $tempDir = Join-Path -Path $ExtractPath -ChildPath ([System.IO.Path]::GetRandomFileName()) } New-Item -Path $tempDir -ItemType Directory | Out-Null Expand-Archive -Path $ArchivePath -DestinationPath $tempDir return $tempDir } return $null } # Fonction pour obtenir la date de création d'une image/vidéo function Get-OriginalDate { param ( $file ) # Tentative de lecture des données EXIF $exif = Try { [System.Drawing.Image]::FromFile($file.FullName) } Catch { $null } if ($exif) { $exifDate = $exif.PropertyItems | Where-Object { $_.Id -eq 0x9003 } | ForEach-Object { [System.Text.Encoding]::ASCII.GetString($_.Value).TrimEnd([char]0) } if ($exifDate) { $date = [datetime]::ParseExact($exifDate, "yyyy:MM:dd HH:mm:ss", $null) } else { $date = $file.CreationTime } $exif.Dispose() } else { $date = $file.CreationTime } } # Demande des paramètres si non fournis if (-not $args[0] -or -not $args[1]) { $SourceDir = Read-Host "Entrez le chemin du dossier source" $DestinationDir = Read-Host "Entrez le chemin du dossier destination" } else { $SourceDir = $args[0] $DestinationDir = $args[1] } # Vérifie si le dossier source est une archive if ($SourceDir -match "\.zip$") { $SourceDir = Decompress-ArchiveIfNeeded -ArchivePath $SourceDir -ExtractPath $env:TEMP if (-not $SourceDir) { Write-Host "L'archive n'a pas pu être décompressée." return } } $validExtensions = Get-ImageVideoExtensions # Parcourt tous les fichiers récursivement dans le dossier source Get-ChildItem -Path $SourceDir -Recurse -File | ForEach-Object { $file = $_ $extension = $file.Extension.ToLower().TrimStart('.') if ($extension -in $validExtensions) { # Tentative de lecture des données EXIF $exif = Try { [System.Drawing.Image]::FromFile($file.FullName) } Catch { $null } if ($exif) { $exifDate = $exif.PropertyItems | Where-Object { $_.Id -eq 0x9003 } | ForEach-Object { [System.Text.Encoding]::ASCII.GetString($_.Value).TrimEnd([char]0) } if ($exifDate) { $originalDate = [datetime]::ParseExact($exifDate, "yyyy:MM:dd HH:mm:ss", $null) } else { $originalDate = $file.CreationTime } $exif.Dispose() } else { $originalDate = $file.CreationTime } if (-Not $originalDate) { $targetFolder = Join-Path -Path $DestinationDir -ChildPath "Non daté" } else { # Créer le dossier de destination basé sur l'année et le mois $year = $originalDate.Year $monthNum = $originalDate.Month.ToString("00") $monthName = $originalDate.ToString("MMMM", [System.Globalization.CultureInfo]::GetCultureInfo("fr-FR")) $targetFolder = Join-Path -Path $DestinationDir -ChildPath "$year\$monthNum - $monthName" } if (-Not (Test-Path $targetFolder)) { New-Item -Path $targetFolder -ItemType Directory | Out-Null } # Copier le fichier dans le dossier de destination Copy-Item -Path $file.FullName -Destination $targetFolder } else { Write-Host "Fichier ignoré: $($file.FullName)" } } # Suppression du dossier temporaire si nécessaire if ($SourceDir -like "$env:TEMP\*") { Remove-Item -Path $SourceDir -Recurse -Force }