Help us understand the problem. What is going on with this article?

PowershellでHash値を算出し重複ファイルを洗い出す

More than 3 years have passed since last update.

日々PCを使っていると、重複したファイルがそこかしこに散らばり
挙句ディスクの空き容量が不足する事態に。
調べるフリーソフトもあるけれど、会社とかのルールで入れられない・わざわざ入れたくないという方へ。

必須環境

  • Windows8.1以降のOS
    • Powershell 4.0のGet-FileHashコマンドを利用するためです。Windows7だけど、MS提供モジュールはインストールできるという方はPowershell4.0導入で対応可能です。
    • Windows Management Framework 4.0をインストールすることでPowershell4.0導入可能です。
  • Powershell3.0以前の環境でも.Net FrameworkのSystem.Security.Cryptography 名前空間を利用することで、SHA256でHash値を取得可能なようです。Get-FileHashコマンドの処理を適宜編集してください。
    • Windows7であれば、Powershell2.0が標準インストールされています。

使い方

  1. 下記Scriptのディレクトリ設定を適当な値に編集し、実行。(*1)
    • $wDir : 作業用ディレクトリの指定します。Hashリストを生成するディレクトリでもあります。
    • $lRoot : 調査対象のトップディレクトリを指定します。
    • 生成されるHashリスト : yyyyMMdd-hhmmss_Hashlist.csv
  2. 完了したら生成されたCSVを開き、Hashでソートして不要なものを削除。
    • CSVのレコード数次第では、Excelで編集したりAccess等のDBで抽出したりしましょう。(*2)

注意事項

  1. SHA256で算出していることもあり、ファイルサイズ・ファイルの数次第ではあるものの想像以上に時間がかかることが想定されます。心してかかりましょう。
    • ファイル数が多い場合、その他アルゴリズムでは重複する可能性が高く対策としてSHA256を採用しています。
  2. Powershellでソートさせたり重複ファイルだけリスト化も不可能ではないですが、そこまでやらせると時間がかかり過ぎるので適宜ツールは使い分けしましょう。

その他

  • 実装出来ていないですが、今後実装したいこと。
    • ファイルサイズも取得してCSVに書き出し
    • 処理の高速化(高速にできるのか!?)
    • 前述のPowershell3.0以前の環境への対応
    • Function化
Get-Hashlist.ps1
# ワーキングディレクトリ設定/ファイル一覧対象ディレクトリルート設定/タイムスタンプ取得
$wDir = "D:\"
$lRoot = "E:\"
$fTimeStamp = Get-Date -Format "yyyyMMdd-hhmmss"

# ワーキングディレクトリへ移動
cd $wDir

# ファイル一覧情報取得
Write-Host (Get-Date)
Write-Host Getting File List ...
$fList = Get-ChildItem -Path $lRoot -Recurse -File
$lCount = $fList.count

# Hash一覧作成
$fPath = ".\"+$fTimeStamp+"_Hashlist.csv"
Write-Host $fPath
for ($i = 0;$i -lt ($lCount);$i++){
 $pPer=$i/($lCount - 1)*100
 Write-Progress -Activity "Hash一覧作成中" `
  -PercentComplete $pPer `
  -CurrentOperation "$lCount : $pPer% complete" `
  -Status "しばらくお待ちください。"
 $fList[($i)] | `
  Get-FileHash -Algorithm SHA256 | `
  Select Hash,Path | `
  Export-CSV -NoTypeInformation -Path $fPath -Append
}

# Hash一覧データレコード数取得
$fRecord=(Import-Csv -Path $fPath).Length

# ファイル件数,Hashレコード数比較
IF ($lCount -eq $fRecord){
 Write-Host Match Record Count. Complete.
} ELSE {
 Write-Host Not Match Record Count. Error.
}

Read-Host "Press Any Key"
nya193
意識遠い系のエンジニアです。お昼寝大好きです。 時限投稿したいときは、はてなブログに書くことがあります。
http://init6.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした