PowerShell Kullanarak Yinelenen Dosyaları Bulma
Projelerden birinde, bir dosya sunucusunun paylaşılan ağ klasöründeki yinelenen dosyaları bulmak için bir PowerShell betiğine ihtiyacım vardı. Windows'ta yinelenen dosyaları bulmak ve kaldırmak için bir dizi üçüncü taraf araç vardır, ancak bunların çoğu ticaridir veya otomatik senaryolar için uygun değildir.
Dosyaların adları farklı ancak içerikleri aynı olabileceğinden, dosyaları yalnızca ada göre karşılaştırmamalısınız. Tüm dosyaların karmalarını almak ve aralarında aynı olanları bulmak daha iyidir.
Aşağıdaki PowerShell tek satırlık komut, bir klasörü (alt klasörleri dahil) tekrar tekrar taramanıza ve yinelenen dosyaları bulmanıza olanak tanır. Bu örnekte, aynı karmalara sahip iki özdeş dosya bulundu:
Get-ChildItem -path C:\Share\ -Recurse | Get-FileHash | Group-Object -property hash | Where-Object { $_.count -gt 1 } | ForEach-Object { $_.group | Select-Object Path, Hash }Bu PowerShell tek astarlı kopyaları bulmak için kullanımı kolaydır, ancak performansı oldukça düşüktür. Klasörde çok sayıda dosya varsa, bunların karmalarını hesaplamak uzun zaman alacaktır. Dosyaları önce boyutlarına göre karşılaştırmak daha kolaydır (hesaplanması gerekmeyen hazır bir dosya özniteliğidir). Ardından, yalnızca aynı boyuttaki dosyaların karmalarını alacağız:
$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 cmdlet'ini kullanarak bir test klasöründe her iki komutun performansını karşılaştırabilirsiniz:
Measure-Command {your_powershell_command}2.000 dosya içeren bir klasör için, ikinci komut ilkinden çok daha hızlıdır (10 dakikaya karşı 3 saniye).
Bir kullanıcıdan silinecek yinelenen dosyaları seçmesini isteyebilirsiniz. Bunu yapmak için, yinelenen dosyaların bir listesini Out-GridView cmdlet'ine aktarın:
$file_dublicates | Out-GridView -Title "Select files to delete" -OutputMode Multiple -PassThru|Remove-Item -Verbose -WhatIfBir kullanıcı tablodan silinecek dosyaları seçebilir (birden fazla dosya seçmek için CTRL'ye basın ve basılı tutun) ve Tamam'ı tıklayın.
Silmek yerine, seçili dosyaları Move-Item kullanarak başka bir dizine taşıyabilirsiniz.
Ayrıca, yinelenen dosyaları sabit bağlantılarla değiştirebilirsiniz. Yaklaşım, dosyaları yerinde tutmaya izin verir ve disk alanından önemli ölçüde tasarruf sağlar.
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
}Dosyayı çalıştırmak için aşağıdaki komut biçimini kullanın:
.\hardlinks.ps1 -dir1 d:\folder1 -dir2 d:\folder2Komut dosyası, statik dosyaların (değişmeyen!) kopyalarını sembolik sabit bağlantılarla bulmak ve değiştirmek için kullanılabilir.
Windows Server'da, dosyaları çoğaltma sorununu çözmek için Dosya Sunucusu rolünün yerleşik Veri Tekilleştirme özelliğini kullanabilirsiniz. Ancak veri tekilleştirme ve artımlı yedekleme kullanırken, yedekten geri yükleme yaparken bazı sıkıntılar yaşarsınız.
Ayrıca, yinelenen dosyaları sabit bağlantılarla değiştirmek için bir konsol dupemerge aracı kullanabilirsiniz.

