LoginSignup
6
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-04-15

日々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"
6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8