כיצד למצוא קבצים כפולים באמצעות PowerShell
עבור אחד הפרויקטים, הייתי זקוק לסקריפט PowerShell כדי למצוא קבצים כפולים בתיקיית הרשת המשותפת של שרת קבצים. ישנם מספר כלים של ספקים חיצוניים לאיתור והסרה של קבצים כפולים ב- Windows, אך רובם מסחריים או אינם מתאימים לתרחישים אוטומטיים.
מאחר שלקבצים עשויים להיות שמות שונים אך תוכן זהה, אין להשוות קבצים לפי שמות בלבד. עדיף לקבל hashes של כל הקבצים ולמצוא את אותם אלה ביניהם.
הפקודה הבאה של PowerShell בשורה אחת מאפשרת לך לסרוק באופן רקורסיבי תיקיה (כולל תיקיות המשנה שלה) ולמצוא קבצים כפולים. בדוגמה זו, נמצאו שני קבצים זהים עם אותם קודי Hash:
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 one-liner קל לשימוש למציאת כפילויות, עם זאת, הביצועים שלה הוא די גרוע. אם יש קבצים רבים בתיקיה, ייקח זמן רב לחשב את קודי ה- hash שלהם. קל יותר להשוות תחילה קבצים לפי גודלם (זוהי תכונת קובץ מוכן שאין צורך לחשב). לאחר מכן נקבל hashes של הקבצים באותו גודל בלבד:
$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 }
ניתן להשוות את הביצועים של שתי הפקודות בתיקיית בדיקה באמצעות ה- cmdlet Measure-Command:
Measure-Command {your_powershell_command}עבור תיקיה המכילה 2,000 קבצים, הפקודה השנייה מהירה בהרבה מהראשונה (10 דקות לעומת 3 שניות).
באפשרותך לבקש ממשתמש לבחור קבצים כפולים למחיקה. לשם כך, העבר רשימה של קבצים כפולים ל- cmdlet Out-GridView:
$file_dublicates | Out-GridView -Title "Select files to delete" -OutputMode Multiple -PassThru|Remove-Item -Verbose -WhatIfמשתמש יכול לבחור קבצים למחיקה בטבלה (לבחירת קבצים מרובים, החזק את מקש CTRL לחוץ) וללחוץ על הלחצן 'אשר'.
במקום למחוק, באפשרותך להעביר את הקבצים שנבחרו לספרייה אחרת באמצעות 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, באפשרותך להשתמש בתכונה המוכללת מניעת כפילויות נתונים של תפקיד שרת הקבצים כדי לפתור את הבעיה של שכפול קבצים. עם זאת, בעת שימוש במניעת כפילויות ובגיבוי מצטבר, תיתקל בכמה בעיות בעת השחזור מהגיבוי.
כמו כן, אתה יכול להשתמש בכלי dupemerge מסוף כדי להחליף שכפול קבצים עם קישורים קשיחים.

