【入門編】【上級プロフェッショナル向け】CertUtil連携によるファイルハッシュ(SHA256)比較とFSOを組み合わせた完全一致データバックアップ – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!バックオフィスや現場の自動化を長年支えてきた、君の頼れる先輩エンジニアです。

今日は、VBScriptとWindows標準の強力なツールを組み合わせた、「ビット単位の完全性を保証する超高信頼性ファイル同期システム」の作り方を伝授するよ。

「マクロの記録」や、ただファイルを上書きするだけのスクリプトはもう卒業だ。
今回は、ファイルサイズと「SHA256ハッシュ値」を完全に突合し、一物たりとも狂いのない真のデータ整合性を担保する、プロフェッショナルなファイルシステム操作の世界へ案内しよう。ここをクリアすれば、君のVBScriptのスキルは間違いなく現場のトップクラスだ。

—

なぜ「ファイルサイズとタイムスタンプ」だけでは不十分なのか?

現場でよくあるファイルバックアップや同期。君はこれまでどう書いていたかな?
多くの場合、FSO(FileSystemObject)を使ってこう書いているはずだ。

‘ よくある従来のコピー(タイムスタンプや存在有無だけで判断)
If fso.FileExists(dstPath) Then
If fso.GetFile(srcPath).DateLastModified > fso.GetFile(dstPath).DateLastModified Then
fso.CopyFile srcPath, dstPath, True
End If
End If

ちょっと待ってほしい。そのアプローチ、実はデータ破損のリスクが潜んでいる。
ネットワークの一瞬の瞬断、ストレージの微細なセクタ不良、あるいはファイル名やタイムスタンプだけが更新されて中身が壊れているケース……。これらは「タイムスタンプの比較」すらすり抜けてしまう。

そこでプロが取るべきアプローチはこれだ。
1. ファイルサイズが完全に一致しているか?
2. SHA256ハッシュ(指紋)が完全に一致しているか?

この2つをクリアした時初めて、「おや、このファイルは完全に同じだ。コピーの必要はない」と判断する。これが今回目指す「完全一致データバックアップ」の本質だ。

—

全体像:FSOとCertUtilの華麗なる連携

VBScript単体では、ファイルの暗号化学的ハッシュ(SHA256など)を高速に計算する機能はない。FSOはあくまで「ファイルシステムの案内役」だからだ。

そこで、Windowsに標準搭載されている最強のコマンドラインツール `CertUtil` をWScript.Shell経由で呼び出し、その結果をVBScriptでスマートに回収・料理する。

[VBScript (FSO)] –(ファイルの存在確認・サイズ比較)–> ターゲット特定
↓
[WScript.Shell] –(CertUtil.exe 呼び出し)–> SHA256ハッシュ文字列取得
↓
[完全一致判定] —-> 一致すればスキップ、不一致なら確実にコピー!

この役割分担が、VBScriptを極限までエレガントに動かす秘訣なんだ。

—

実装コード:完全版ハッシュ検証バックアップシステム

さあ、現場でそのままコピー&ペーストして使える実用スクリプトを公開しよう。
デスクトップなどに `SecureSync.vbs` という名前で保存して、中身をじっくり読んでみてほしい。

‘ ==============================================================================
‘ 処理名: CertUtil連携・SHA256検証付き高信頼性ファイル同期スクリプト
‘ 概要 : コピー元とコピー先のサイズおよびSHA256ハッシュを比較し、
‘ 完全一致する場合のみコピーをスキップするプロ仕様の同期ルーチン。
‘ ==============================================================================
Option Explicit

‘ メイン処理の実行
Sub Main()
Dim srcFile, dstFolder
‘ 【環境に合わせてパス書き換えてね】
srcFile = “C:\Work\ImportantData.xlsx”
dstFolder = “D:\Backup\”

WScript.Echo “=== 同期処理を開始します ===”

If SyncFileWithHashCheck(srcFile, dstFolder) Then
WScript.Echo “処理結果: ファイルは正常に同期(または検証完了)しました。”
Else
WScript.Echo “処理結果: エラーが発生しました。”
End If
End Sub

‘ — コア関数:ハッシュ検証付き同期ロジック —
Function SyncFileWithHashCheck(ByVal sourcePath, ByVal destinationDir)
Dim fso, shell, srcFileObj, dstPath, dstFileObj
Dim srcHash, dstHash

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)

‘ 1. コピー元ファイルの存在確認
If Not fso.FileExists(sourcePath) Then
WScript.Echo “[ERROR] コピー元ファイルが存在しません: ” & sourcePath
SyncFileWithHashCheck = False
Exit Function
End If

‘ 2. コピー先フォルダの存在確認・自動生成
If Not fso.FolderExists(destinationDir) Then
fso.CreateFolder(destinationDir)
WScript.Echo “[INFO] コピー先フォルダを新規作成しました: ” & destinationDir
End If

Set srcFileObj = fso.GetFile(sourcePath)
dstPath = fso.BuildPath(destinationDir, srcFileObj.Name)

‘ 3. コピー先が未存在なら、ハッシュ計算不要で即コピー
If Not fso.FileExists(dstPath) Then
WScript.Echo “[INFO] コピー先が未存在のため新規コピーします。”
srcFileObj.Copy dstPath, True
SyncFileWithHashCheck = True
Exit Function
End If

Set dstFileObj = fso.GetFile(dstPath)

‘ 4. 高速プレチェック:ファイルサイズの比較
‘ サイズが違えばハッシュ計算するまでもなく「別物」と断定できる(パフォーマンスの最適化)
If srcFileObj.Size <> dstFileObj.Size Then
WScript.Echo “[INFO] ファイルサイズが異なるため、更新を実行します。”
srcFileObj.Copy dstPath, True
SyncFileWithHashCheck = True
Exit Function
End If

‘ 5. 厳密チェック:SHA256ハッシュ値の抽出と比較
WScript.Echo “[INFO] サイズが一致しました。SHA256ハッシュを検証中…”
srcHash = GetSHA256Hash(sourcePath, shell, fso)
dstHash = GetSHA256Hash(dstPath, shell, fso)

If srcHash = “” Or dstHash = “” Then
WScript.Echo “[ERROR] ハッシュ値の取得に失敗しました。”
SyncFileWithHashCheck = False
Exit Function
End If

WScript.Echo ” – SRC: ” & srcHash
WScript.Echo ” – DST: ” & dstHash

‘ 6. 最終判定
If srcHash = dstHash Then
WScript.Echo “[SUCCESS] ハッシュが完全に一致しました。無駄なコピーをスキップします。”
Else
WScript.Echo “[INFO] ハッシュが不一致です。ファイルを上書き更新します。”
srcFileObj.Copy dstPath, True
End If

SyncFileWithHashCheck = True
End Function

‘ — ヘルパー関数:CertUtilを利用してSHA256文字列を抽出する鬼門の処理 —
Function GetSHA256Hash(ByVal filePath, ByVal shell, ByVal fso)
Dim cmd, exec, output, lines, i, targetLine
GetSHA256Hash = “”

‘ CertUtilコマンドの組み立て(スペースや日本語パス対策としてダブルクォーテーションで囲む)
cmd = “certutil -hashfile “”” & filePath & “”” SHA256″

‘ Runではなく Exec を使うことで、標準出力ストリームをキャプチャする
Set exec = shell.Exec(cmd)
output = exec.StdOut.ReadAll()

‘ CertUtilの出力結果は複数行になり、2行目にハッシュ値が出力される仕様
‘ 例:
‘ 履歴:
‘ ハッシュ (sha256):
‘ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
‘ CertUtil: -hashfile コマンドは正常に完了しました。

lines = Split(output, vbCrLf)
If UBound(lines) >= 1 Then
‘ 空白や余分な文字を取り除いてハッシュ値のみをクリーンアップ
targetLine = Trim(lines(1))
‘ ハイフンやスペース(コロン等)が含まれていない、純粋なHEX文字列の行を探す
For i = 0 To UBound(lines)
Dim candidate
candidate = Trim(lines(i))
‘ SHA256の長さは通常64文字の16進数
If Len(candidate) = 64 Then
GetSHA256Hash = LCase(candidate)
Exit Function
End If
Next
End If
End Function

‘ エントリポイントの呼び出し
Main()

—

コードの深掘り解説:エンジニアが押さえるべき3つのポイント

1. パフォーマンスの最適化(フェイル・ファストの原則)

コードのステップ4を見てほしい。いきなり重いハッシュ計算をするのではなく、まず `srcFileObj.Size <> dstFileObj.Size` でサイズを比較しているね。
サイズが違うなら、中身が一致する可能性はゼロだ。無駄なコマンド実行を避けるこの一手間が、大規模なフォルダを同期する際の処理速度を劇的に向上させるんだ。

2. `WshShell.Exec` と `StdOut.ReadAll` の組み合わせ

VBScriptで外部コマンドの結果を受け取る際、`Run` メソッドでは戻り値(終了コード)しか取れない。
しかし、`Exec` メソッドを使えば、コマンドが吐き出したコンソール出力をそのままVBScript側の変数(メモリ上)にキャプチャできる。この挙動の仕組みを知っているだけで、VBScriptでできることの幅が何倍にも広がるよ。

3. CertUtilの出力ゆらぎに対する堅牢性

`CertUtil` コマンドはWindowsのバージョン(Windows 10, 11, Windows Server等)や言語ロケールによって、出力フォーマットの行数が微妙に変わることがある。
そのため、今回の `GetSHA256Hash` 関数では、出力されたテキストを `Split` で行に分解し、「文字数がぴったりの64文字(SHA256のHEX長)の行を探し出す」という堅牢なアルゴリズムを採用している。これにより、環境変化によるバグを綺麗に回避しているんだ。

—

陥りやすい罠とトラブルシューティング

現場でこのスクリプトを動かすとき、いくつかの「落とし穴」にハマることがある。先輩から事前に注意点を伝えておこう。

  • パスにスペースが含まれる問題

`cmd = “certutil -hashfile “”” & filePath & “”” SHA256″` の部分。ファイルパスの中にスペース(例: `C:\My Folder\data.txt`)が含まれている場合、ダブルクォーテーションでパスを囲まないとCertUtilがファイルを見つけられずにエラー終了する。コード内のトリプルクォーテーション `”””` によるエスケープの技はしっかりマスターしておこう。

  • セキュリティソフトの誤検知

稀に、VBScriptから `CertUtil.exe` を頻繁に呼び出す挙動を、過敏なEDR(エンドポイント検出・対応)製品が「不審なスクリプト活動」と検知することがある。もし社内PCでブロックされた場合は、IT部門にスクリプトの意図を説明して除外設定をしてもらう必要があるので注意してね。

—

まとめ:VBScriptの限界を超える知見

今回は、FSOの基礎的なファイル操作に留まらず、OSのネイティブコマンド(CertUtil)を巧みに連係させ、データのビット単位の同一性を保証する「プロフェッショナルな同期システム」を解説した。

「たかがVBScript」と侮るなかれ。オブジェクトのライフサイクルを理解し、OSの機能と組み合わせれば、業務自動化の強力な武器として現役バリバリで活躍させることができるんだ。

ここをクリアした君なら、もう初級者ではない。ぜひ自身の業務や管理するサーバーのバックアップスクリプトに応用して、周囲をあっと言わせるシステムを組み上げてみてほしい!

タイトルとURLをコピーしました