Gérer les fichiers dupliqués sur un partage réseau peut vite devenir un casse-tête, surtout lorsqu’on essaie d’automatiser le processus ou de limiter l’encombrement du disque. Heureusement, PowerShell propose des solutions intéressantes, mais son principal inconvénient est sa lenteur avec un grand nombre de fichiers. La solution, comme toujours, consiste à optimiser le processus : comparer d’abord les fichiers par taille plutôt que de calculer leur hachage immédiatement. C’est un peu une solution de contournement, mais elle accélère considérablement le traitement des dossiers volumineux.
Comment trouver et gérer les fichiers en double sur un serveur de fichiers avec PowerShell
Méthode 1 : Comparaison simple des hachages (lente, mais simple)
Cette méthode calcule le hachage de tous les fichiers et les regroupe par hachage identique afin d’identifier les doublons. Elle est pratique pour les petits dossiers ou lorsque la précision est primordiale. Sur certaines configurations, le traitement peut prendre un certain temps, surtout avec des milliers de fichiers. Prévoyez une durée d’exécution de quelques minutes, voire plus selon le nombre de fichiers. Voici une méthode simple pour l’exécuter :
Get-ChildItem –path C:\Share\ -Recurse | Get-FileHash | Group-Object -property hash | Where-Object { $_.count -gt 1 } | ForEach-Object { $_.group | Select-Object Path, Hash }
Il affichera les chemins des fichiers correspondants ayant des hachages identiques. C’est assez étrange, mais sur certaines machines, la première exécution peut provoquer un écran bleu ou un blocage, puis tout fonctionne correctement par la suite. Il s’agit peut-être d’un problème de cache ou d’un comportement inhabituel de PowerShell.
Méthode 2 : Accélérer le processus en filtrant d’abord par taille.
Sur une configuration, ça a fonctionné à merveille, mais sur une autre, je jure que le temps d’exécution est passé de 10 minutes à 3 secondes ! Sans blague. En gros, on commence par regrouper les fichiers par taille, car les attributs de taille sont rapides à lire et ne nécessitent pas de hachage. Ensuite, on compare uniquement les hachages des fichiers de même taille. Voici comment ça se passe :
$file_dublicates = Get-ChildItem –path C:\Share\ -Recurse | Group-Object -property Length | Where-Object { $_.count -gt 1 } | Select-Object –Expand Group | Get-FileHash | Group-Object -property hash | Where-Object { $_.count -gt 1 } | ForEach-Object { $_.group | Select-Object Path, Hash }
Ainsi, vous effectuez moins de hachages au total, ce qui accélère le processus. Vous pouvez tester et comparer les deux commandes avec Measure-Command, comme ceci :
Measure-Command { }
Conseil de pro : si vous traitez des milliers de fichiers, privilégiez le tri par taille ; c’est beaucoup plus rapide. J’ai souvent constaté que le filtre de taille réduisait le temps de traitement de plusieurs minutes à quelques secondes.
Facultatif : Inviter l’utilisateur à supprimer ou déplacer les doublons
C’est plutôt pratique : après avoir rassemblé les doublons, vous pouvez laisser l’utilisateur choisir les éléments à supprimer ou à déplacer. Utilisez Out-GridView pour afficher un tableau de sélection, puis supprimez ou déplacez les fichiers sélectionnés.
$file_dublicates | Out-GridView -Title "Select files to delete" -OutputMode Multiple –PassThru | Remove-Item –Verbose –WhatIf
Dans la grille, maintenez la touche CTRL enfoncée pour sélectionner plusieurs fichiers, cliquez sur OK, et ils seront supprimés (ou déplacés vers un autre dossier si vous préférez).Si vous souhaitez conserver une organisation sans supprimer de fichiers, remplacez Remove-Item par Move-Item.
$file_dublicates | Out-GridView...| Move-Item -Destination D:\DuplicateBackups
Vous pouvez même remplacer les doublons par des liens physiques pour gagner de l’espace, surtout si ces fichiers ne sont pas susceptibles d’être modifiés. Il existe un script appelé Winhance ; vous pouvez aussi créer le vôtre avec un script qui repère les doublons et crée des liens physiques au lieu de conserver plusieurs copies. Utilisez fsutil si nécessaire pour créer directement les liens, mais attention : cette commande requiert des droits d’administrateur.
param( [Parameter(Mandatory=$True)] [ValidateScript({Test-Path -Path $_ -PathType Container})] [string]$dir1, [Parameter(Mandatory=$True)] [ValidateScript({(Test-Path -Path $_ -PathType Container) -and $_ -ne $dir1})] [string]$dir2 ) Get-ChildItem -Recurse $dir1, $dir2 | Group-Object Length | Where-Object {$_. Count -ge 2} | Select-Object -ExpandGroup | Get-FileHash | Group-Object -Property hash | Where-Object { $_. Count -ge 2 } | ForEach-Object { $f1 = $_. Group[0].Path # Remove the duplicate file Remove-Item $f1 # Create a hard link (example, actual command may vary) # fsutil hardlink create $f1 $_. Group[1].Path }
Ce script est particulièrement pratique pour les fichiers statiques qui ne changent pas. Sur Windows Server, des fonctionnalités comme la déduplication des données peuvent automatiser la plupart de ces opérations, mais attention : la déduplication peut parfois compliquer les restaurations à partir de sauvegardes. Pour les configurations plus modestes ou les utilisateurs avertis en scripting, un outil en ligne de commande comme dupemerge permet d’automatiser efficacement le remplacement des fichiers par des liens physiques.
En résumé, un flux de travail efficace consiste d’abord à filtrer par taille, puis à hacher les fichiers, et enfin à proposer des options de nettoyage à l’utilisateur si nécessaire. Rien de magique, juste une méthode éprouvée qui remplace avantageusement la recherche manuelle dans des milliers de fichiers.