Amazon10/19まで!プライム感謝祭開催中!セール会場へ

バックアップが本当に戻せるかを確かめる方法|Windowsで復元テストの手順

バックアップを取っている状態と、そこから戻せる状態は同じではない。

コピー先が途中で止まっていた、対象から外れていたフォルダーがあった、戻したファイルが壊れていた、といった食い違いは、実際に戻すまで表に出ない。

ここでは、いま使っているバックアップが戻せるかどうかを、元のデータに触れずに確かめる手順を整理する。

改訂した復元・比較スクリプトは2026年10月2日にWindows PowerShell 5.1で、隔離した練習用フォルダーを使って実行した。

目次

復元テストで確かめるのは3つ

戻せるかどうかは、次の3点に分かれる。

確かめること分からないと起きること見る方法
取れているか対象から外れたフォルダーが丸ごと無いファイル数を数えて比べる
戻せるか戻す操作そのものが失敗する別の場所へ実際に戻す
中身が同じか戻ったが開けない、途中で切れているハッシュで突き合わせる
3つは別のこと。1つ確かめても他は分からない

ファイル数だけを比べると、中身が壊れていても気づけない。

逆にハッシュだけを見ると、そもそも対象から外れていたフォルダーには気づけない。

元のデータを上書きしない場所へ戻す

復元テストで最も避けたいのは、テストそのものが元のデータを壊すことである。

改訂版のスクリプトでは、元とバックアップから独立した未作成のフォルダー名を指定する。スクリプトが復元先を新しく作る。

元の場所へ戻す操作は、テストではなく本番の復旧であり、試す目的で実行しない。

  • 元とバックアップの外へ、未作成の復元先を決める
  • 元のフォルダーと、戻した先の両方を残したまま比べる
  • 比べ終わるまで、戻した先を消さない

手順1 戻す(robocopyの終了コードを見る)

次の内容をrestore-test.ps1としてUTF-8(BOM付き)で保存する。通常のローカルフォルダーを対象とし、未作成の復元先を指定する。

param([Parameter(Mandatory=$true)][string]$Original,
      [Parameter(Mandatory=$true)][string]$Backup,
      [Parameter(Mandatory=$true)][string]$Output)
$ErrorActionPreference = 'Stop'
function Get-Tree([string]$Root) {
  $base = (Get-Item -LiteralPath $Root -Force -ErrorAction Stop).FullName.TrimEnd('\')
  if (-not (Get-Item -LiteralPath $base -Force).PSIsContainer) { throw 'フォルダーを指定してください' }
  $rows = New-Object 'System.Collections.Generic.List[string]'
  $rows.Add('#ROOT')
  function Visit([string]$Path) {
    foreach ($item in Get-ChildItem -LiteralPath $Path -Force -ErrorAction Stop) {
      if ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'リンク・ジャンクションは対象外です' }
      $rel = $item.FullName.Substring($base.Length + 1)
      if ($item.PSIsContainer) {
        $rows.Add('D:' + $rel)
        Visit $item.FullName
      } else {
        $hash = (Get-FileHash -LiteralPath $item.FullName -Algorithm SHA256 -ErrorAction Stop).Hash
        $rows.Add('F:' + $rel + ':' + $hash)
      }
    }
  }
  if ((Get-Item -LiteralPath $base -Force).Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'リンクは対象外です' }
  Visit $base
  $rows | Sort-Object
}

$a = (Get-Item -LiteralPath $Original -Force).FullName.TrimEnd('\')
$b = (Get-Item -LiteralPath $Backup -Force).FullName.TrimEnd('\')
$dest = [IO.Path]::GetFullPath($Output).TrimEnd('\')
if (Test-Path -LiteralPath $dest) { throw '復元先は未作成の場所にしてください' }
foreach ($src in @($a, $b)) {
  if ($dest -eq $src -or $dest.StartsWith($src + '\', [StringComparison]::OrdinalIgnoreCase) -or $src.StartsWith($dest + '\', [StringComparison]::OrdinalIgnoreCase)) { throw '復元先と入力の包含関係は禁止です' }
}
$before = @(Get-Tree $a)
$backupBefore = @(Get-Tree $b)
New-Item -ItemType Directory -Path $dest -ErrorAction Stop | Out-Null
& robocopy.exe $b $dest /E /XJ /R:1 /W:1 /NFL /NDL /NJH /NP | Out-Host
$copyCode = $LASTEXITCODE
Write-Host "RobocopyExit=$copyCode"
if ($copyCode -ge 8) { throw 'コピー失敗。出力は未完成です' }
$restored = @(Get-Tree $dest)
$difference = @(Compare-Object $before $restored)
if (@(Compare-Object $before @(Get-Tree $a)).Count -or @(Compare-Object $backupBefore @(Get-Tree $b)).Count) { throw '検証中に入力が変わりました' }
$difference | Select-Object SideIndicator,InputObject | ConvertTo-Json
if ($difference.Count) { throw '相対パス・ファイル内容・空フォルダーに差があります' }
Write-Host '対象の通常ファイルとフォルダーが一致しました'

robocopyは終了コードで結果を返すため、コードを確認し、その後にファイルとフォルダーを照合する。

powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File ".\restore-test.ps1" -Original ".\original" -Backup ".\backup" -Output ".\restore-new"
終了コード意味扱い
0コピーする必要のあるファイルがなかった指定した入力と照合結果を確認する
1ファイルをコピーした成功。次の手順へ
2コピー先にだけ余分なものがある内容を確かめる
3コピーした、かつ余分なものもある内容を確かめる
8以上コピーできなかったものがある失敗として扱う
robocopyの終了コードの読み方

手元で3ファイルをコピーしたときの終了コードは1だった。

0はコピーする必要のあるファイルがなかった場合にも返る。すでに同じ内容のコピー先でも0になるため、指定した入力と照合結果を確認する。

8以上が返ったときは、その時点で失敗として扱い、次の手順へ進まない。

手順2 中身が同じかをハッシュで突き合わせる

ファイル数が合っていても、中身が同じとは限らない。

元と戻した先の両方でハッシュを取り、突き合わせる。

function Get-Tree([string]$Root) {
  $base = (Get-Item -LiteralPath $Root -Force -ErrorAction Stop).FullName.TrimEnd('\')
  if (-not (Get-Item -LiteralPath $base -Force).PSIsContainer) { throw 'フォルダーを指定してください' }
  $rows = New-Object 'System.Collections.Generic.List[string]'
  $rows.Add('#ROOT')
  function Visit([string]$Path) {
    foreach ($item in Get-ChildItem -LiteralPath $Path -Force -ErrorAction Stop) {
      if ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'リンク・ジャンクションは対象外です' }
      $rel = $item.FullName.Substring($base.Length + 1)
      if ($item.PSIsContainer) {
        $rows.Add('D:' + $rel)
        Visit $item.FullName
      } else {
        $hash = (Get-FileHash -LiteralPath $item.FullName -Algorithm SHA256 -ErrorAction Stop).Hash
        $rows.Add('F:' + $rel + ':' + $hash)
      }
    }
  }
  if ((Get-Item -LiteralPath $base -Force).Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'リンクは対象外です' }
  Visit $base
  $rows | Sort-Object
}

$a = @(Get-Tree ".\original")
$b = @(Get-Tree ".\restore-new")
Compare-Object $a $b | Select-Object SideIndicator,InputObject

パスの先頭を切り落としているのは、置き場所が違っても同じファイルとして比べるためである。

何も出力されなければ、比較した通常ファイルの相対パスとSHA-256、およびフォルダーの相対パスが一致している。ACL、代替データストリーム、暗号化属性やOS全体の復元を検証するものではない。

手元では3ファイルをコピーした直後に実行し、出力は空だった。

壊れていたときの出方

戻した側の1ファイルだけを書き換えてから、同じコマンドを実行した。

SideIndicator rel
------------- ---
=>            \b.txt
<=            \b.txt

改訂版ではInputObjectにF:相対パス:ハッシュを表示する。同じ相対パスでもハッシュが違えば2行出て、矢印の向きが分かれる。

これは「両方に存在するが、ハッシュが違う」という意味になる。

出方意味
同じrelが2行、矢印が両方向両方にあるが中身が違う
矢印が元の側だけ戻した先にそのファイルが無い
矢印が戻した先だけ元に無いファイルが戻した先にある
Compare-Objectの出方の読み方

ファイル履歴やイメージを使っている場合

Windowsの標準機能を使っている場合も、確かめる形は変わらない。

戻す操作の入り口が違うだけで、別の場所へ戻してハッシュで比べる流れは同じである。

使っている仕組み戻す入り口テストのときの注意
ファイル履歴コントロールパネルのファイル履歴から個人用ファイルを復元復元先を元のフォルダーにしない
OneDriveなどの同期Webの版管理から取り出す同期フォルダーの外へ出して比べる
自分でコピーしているコピー先から取り出すコピー元と同時に開いたまま比べる
仕組みが違っても、別の場所へ戻して比べる点は同じ

ファイル履歴の動作状況は、サービスの状態からも確かめられる。

Get-Service -Name fhsvc | Select-Object Name,DisplayName,Status,StartType

手元の環境ではStatusがStopped、StartTypeがManualと表示された。

この表示は、機能が有効かどうかを直接示すものではないため、設定画面の側もあわせて見る。

点検を続ける形にする

一度戻せたことは、次も戻せることを保証しない。

対象フォルダーが増えたり、保存先の空き容量が尽きたりすると、そこから先が取れなくなる。

  • 月に一度、同じ手順で1つのフォルダーだけ戻して比べる
  • 確かめた日と、そのときのファイル数を書き留める
  • 保存先の空き容量を同じタイミングで見る
  • 対象フォルダーを増やしたら、その月のうちに1回試す

全部を戻すテストは時間がかかるため、続けられる大きさに絞るほうが結果的に回数を重ねられる。

練習で検出した差と復元の範囲

練習用PDF・PNG・検証スクリプトをダウンロード(ZIP)。

2026年10月2日に作った架空の文字と模様で、個人情報や実務の資料は含みません。

ZIPのrestore-test.ps1と記事内のスクリプトは同じ内容です。

originalとbackupの2つの練習用フォルダーに同じファイルを入れ、未作成のrestore-newへ戻します。

出力がすでに存在する場合や、入力の内側・外側に出力を重ねる指定ではコピー前に止まります。

2026年10月2日に実行した条件結果
日本語と角括弧のファイル名、隠しファイル、0バイトファイル、空フォルダー復元して相対パス・バイト内容・フォルダーが一致
既存の復元先、入力内の復元先コピー前に拒否
バックアップの1ファイルを変更/不足/追加3ケースとも照合で不一致を検出

Get-Treeは絶対パスへ解決してから相対パスを作り、-LiteralPathと-Forceで角括弧や隠しファイルも扱います。

空フォルダーも比較し、リンクやジャンクションは対象外として止めます。

失敗後の新しい出力は未完成として保持し、原因を確認してから別の未作成の場所で再試行します。

robocopyの/R:1 /W:1は、失敗時の再試行を1回、間隔を1秒へ制限します。

標準設定は100万回・30秒のため、短い復元テストでは明示します。

2・3は余分な項目、5・6・7は不一致などを含むため、8未満でも照合を省略しません。

この確認は同じPC内の練習用ファイルをコピーして戻したものです。

外付けディスク、クラウドの版管理、Windowsのシステムイメージ、ファイル履歴の実際の復元操作は未検証です。

現在のバックアップに含めたいフォルダーがそろっているかは、元とバックアップの対象範囲を別に確認します。

Microsoftのrobocopy仕様を2026年10月2日に確認しました。

元に戻す際は検証用コピーを本番へ上書きせず、保持した元と、必要な版のバックアップを使います。

あなたはどっち?利用環境に合わせた最適プラン判定フロー

使っているバックアップの仕組みから順に当てはめると、復元テストの入り口が決まります。2026年10月2日にWindows PowerShell 5.1で、隔離した練習用フォルダーを使って確認した内容にもとづく目安です。

  1. まず、取れているか(ファイル数)、戻せるか(実際に別の場所へ戻す)、中身が同じか(ハッシュ)の3点が別のことだと理解する。
  2. 元のデータとバックアップの外に、まだ作っていない復元先のフォルダー名を決める。
  3. ファイル履歴なら、コントロールパネルから個人用ファイルを復元する。復元先は元のフォルダーにしない。
  4. OneDriveなどの同期なら、Webの版管理から取り出し、同期フォルダーの外へ出して比べる。
  5. 自分でコピーしているなら、コピー先から取り出し、コピー元と同時に開いたまま比べる。
  6. 月に一度、1つのフォルダーだけ戻して比べ、確かめた日とファイル数を書き留める。

元の場所へ戻す操作はテストではなく本番の復旧です。試す目的では実行しないでください。

まとめ

  • 取れているか、戻せるか、中身が同じかは別のことなので、3つとも確かめる
  • 改訂版の復元先は未作成の場所にし、スクリプトに作成させる
  • robocopyは画面ではなく終了コードで判断する。1はコピー成功、8以上は失敗
  • Get-FileHashとCompare-Objectで、相対パスとハッシュの組を突き合わせる
  • 同じ相対パスが2行、矢印が両方向に出たら、中身が違っている
  • 月に一度、小さい範囲でよいので続けて試す

コマンドレットの詳細はMicrosoft Learnのリファレンスで確認できる。

Windowsの作業を楽にする道具はPCメソッドのまとめにも置いている。

この改訂の練習データとコードは、記事内のZIPから取得できます。

よくある質問:バックアップの復元テストで迷ったときのチェックリスト

バックアップを取っていれば戻せますか?

同じではありません。コピー先が途中で止まっていた、対象から外れたフォルダーがあった、戻したファイルが壊れていたといった食い違いは、実際に戻すまで表に出ません。

ファイル数を比べるだけで十分ですか?

足りません。ファイル数だけでは、中身が壊れていても気づけません。逆にハッシュだけでは、対象から外れていたフォルダーに気づけません。

復元テストはどこへ戻せばよいですか?

元のデータとバックアップの外にある、まだ作っていないフォルダーへ戻します。元のフォルダーと、戻した先の両方を残したまま比べ、比べ終わるまで戻した先を消さないでください。

ファイル履歴を使っているときの注意は?

復元先を元のフォルダーにしないことです。fhsvcサービスの状態は参考になりますが、機能が有効かどうかを直接示すものではないため、設定画面も合わせて見ます。

一度戻せたら、ずっと安心ですか?

安心できません。対象フォルダーが増えたり、保存先の空き容量が尽きたりすると、そこから先が取れなくなります。月に一度、1つのフォルダーだけ同じ手順で試す形にします。

この記事のスクリプトは実機で確かめていますか?

2026年10月2日にWindows PowerShell 5.1で、隔離した練習用フォルダーを使って実行しました。実務のバックアップやファイル履歴の実機復元は、この確認に含まれていません。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

仕事効率化のおすすめ書籍

仕事用PCの選び方

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次