Как найти дубликаты файлов с помощью PowerShell

Для одного из проектов мне понадобился сценарий PowerShell для поиска дубликатов файлов в общей сетевой папке файлового сервера. Существует ряд сторонних инструментов для поиска и удаления дубликатов файлов в Windows, но большинство из них являются коммерческими или не подходят для автоматических сценариев.

Поскольку файлы могут иметь разные имена, но идентичное содержимое, не следует сравнивать файлы только по имени. Лучше получить хэши всех файлов и найти среди них одинаковые.

Следующая однострочная команда PowerShell позволяет рекурсивно просканировать папку (включая ее подпапки) и найти дубликаты файлов. В этом примере были найдены два одинаковых файла с одинаковыми хэшами:

Get-ChildItem –path C:\Share\ -Recurse | Get-FileHash | Group-Object -property hash | Where-Object { $_.count -gt 1 } | ForEach-Object { $_.group | Select-Object Path, Hash }

Поиск дубликатов файлов с помощью PowerShellПоиск дубликатов файлов с помощью PowerShell

Этот однострочник PowerShell прост в использовании для поиска дубликатов, однако его производительность довольно низкая. Если в папке много файлов, вычисление их хэшей займет много времени. Проще сначала сравнить файлы по размеру (это готовый атрибут файла, который не нужно вычислять). Тогда мы получим хэши только файлов с одинаковым размером:

$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 }

Вы можете сравнить производительность обеих команд на тестовой папке с помощью функции Команда Measure-Command:

Measure-Command {your_powershell_command}

Для папки, содержащей 2 000 файлов, вторая команда работает гораздо быстрее первой (10 минут против 3 секунд).

Можно предложить пользователю выбрать дубликаты файлов для удаления. Для этого передайте список дубликатов файлов в команду Out-GridView:

$file_dublicates | Out-GridView -Title "Select files to delete" -OutputMode Multiple –PassThru|Remove-Item –Verbose –WhatIf

сценарий powershell для поиска дубликатов файлов в windowspowershell скрипт для поиска дубликатов файлов в windows

Пользователь может выбрать файлы для удаления в таблице (чтобы выбрать несколько файлов, нажмите и удерживайте кнопку CTRL) и нажмите OK.

Вместо удаления можно переместить выбранные файлы в другой каталог, используя Move-Item.

Также можно заменить дублирующиеся файлы жесткими ссылками. Такой подход позволяет сохранить файлы на своих местах и значительно экономит дисковое пространство.

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 -Expand Group | Get-FileHash |
Group-Object hash | Where-Object {$_.Count -ge 2} |
Foreach-Object {
$f1 = $_.Group[0].Path
Remove-Item $f1
New-Item -ItemType HardLink -Path $f1 -Target $_.Group[1].Path | Out-Null
#fsutil hardlink create $f1 $_.Group[1].Path
}

Чтобы запустить файл, используйте следующий формат команды:

.\hardlinks.ps1 -dir1 d:\folder1 -dir2 d:\folder2

Сценарий можно использовать для поиска и замены дубликатов статических файлов (которые не меняются!) с символическими жесткими ссылками.

В Windows Server для решения проблемы дублирования файлов можно использовать встроенную функцию Data Deduplication роли File Server. Однако при использовании дедупликации и инкрементного резервного копирования возникают некоторые проблемы при восстановлении из резервной копии.

Также можно использовать консоль dupemerge инструмент для замены дублирующихся файлов жесткими ссылками.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *