PowerShell Format-Volume -WhatIf が効かない原因とフォーマット事故を防ぐ安全対策

PowerShellの-WhatIfは「実行せずに結果だけ確認できる」安全弁として定番です。しかし、Format-Volumeに-WhatIfを付けたのに実際にボリュームがフォーマットされてしまった、という報告があります。本記事では原因と、現場で事故を防ぐ具体策、万一の復旧の初動を整理します。

目次

現象の概要:-WhatIf なのに Format-Volume が実行される

問い合わせの発端は、次のように -WhatIf を付けて実行したにもかかわらず、対象ドライブ(例:D:)がフォーマットされてしまった、というものです。

Format-Volume -WhatIf -DriveLetter D -FileSystem NTFS

通常、-WhatIf は「実行したら何が起きるか」を表示するだけで、実処理は行わないはずです。そのため、Active Directory やファイルサーバーなど“止められない”環境で破壊的なコマンドを投げる前の最終確認として、-WhatIf を信頼してきた方ほど衝撃が大きくなります。

しかし、ストレージ操作(フォーマット、パーティション操作、ディスク初期化など)は一度走ると取り返しがつかない領域が多く、「-WhatIf がある=安全」ではありません。とくに Format-Volume は“結果が即データ消失”になり得るため、挙動の理解と運用の多重防御が重要です。

結論:Format-Volume の -WhatIf は「動作しない」と公式に注記されている

まず押さえておきたいポイントは、Microsoft Learn の Format-Volume 公式ドキュメントに「-WhatIf はこのコマンドレットでは動作しない」旨の注記が明記されていることです。

ドキュメント上では -WhatIf の説明自体は「実行された場合の動作を表示し、コマンドレットは実行しない」と書かれていますが、同じ箇所に 「ただし、このコマンドレットでは WhatIf は機能しない」 という注意書きが付いています。

つまり、今回の「-WhatIf を付けたのにフォーマットされた」という報告は、少なくとも現行ドキュメントの前提では “想定外の挙動”ではなく、そもそも WhatIf に依存できないコマンド として扱うのが現実的です。

背景:なぜ -WhatIf が効かないのか(ShouldProcess と共通パラメーターの落とし穴)

PowerShell の -WhatIf / -Confirm は「共通パラメーター」として知られていますが、共通パラメーターは PowerShell 側で提供される一方で、すべてのコマンドで期待通りに“効果がある”とは限らない点が落とし穴です。

原理的には、破壊的な処理を行う cmdlet / 関数は ShouldProcess(SupportsShouldProcess)を使って「実行してよいか」を都度判断し、-WhatIf が付いたときは実行せずに説明だけ出す、という流れになります。

ところが、Format-Volume は公式に「WhatIf が動かない」とされているため、-WhatIf を付けたからといって“安全停止”しません。ストレージ系の一部コマンドは内部的に CIM / API 呼び出しで実処理が進むことがあり、PowerShell の -WhatIf で完全にガードできないケースがあります。

-Confirm も万能ではない:$ConfirmPreference の影響

「では -Confirm を使えば良いのでは?」という発想も自然ですが、確認プロンプトの出方は $ConfirmPreference(既定値は High)や cmdlet 側の ConfirmImpact に左右されます。

そのため、運用では次の考え方が現実的です。

  • -WhatIf と -Confirm は“補助輪”としては便利だが、ストレージ破壊系では最後の安全装置にしない
  • 「実行されても被害が出ない状態」を先に作る(オフライン化、読み取り専用化、テスト環境化など)

まず行うべき確認:環境情報と対象ボリュームの特定

Microsoft Q&A の受け入れ回答でも、最初に $PSVersionTable を提示し、環境情報と再現条件を揃えたうえでドキュメント側へフィードバックする流れが勧められています。

PowerShell / モジュールの確認

最低限、次を控えておくとトラブルシュートと再発防止に役立ちます。

$PSVersionTable

Get-Command Format-Volume | Select-Object Name, Version, Source

Get-Module Storage -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 Name, Version, Path

「D: だから大丈夫」を捨てる:対象を実体で確定する

ドライブレターは入れ替わることがあります。外付けディスク、SAN、仮想ディスク、クラスタ、メンテナンス中の一時マウントなど、現場ほど “思い込み” が事故に直結します。実行前に、ドライブレター→パーティション→ディスク を辿って実体を確認してください。

# ドライブレターから実体を追跡
$dl = 'D'

$part = Get-Partition -DriveLetter $dl
$disk = $part | Get-Disk
$vol  = Get-Volume -DriveLetter $dl

$vol  | Select-Object DriveLetter, FileSystemLabel, FileSystem, DriveType, HealthStatus, Size, SizeRemaining | Format-List
$part | Select-Object DiskNumber, PartitionNumber, Type, Size, Offset | Format-List
$disk | Select-Object Number, FriendlyName, SerialNumber, BusType, PartitionStyle, Size, IsSystem, IsBoot, IsReadOnly, IsOffline | Format-List
確認したいことコマンド例見るべきポイント事故を防ぐ狙い
PowerShell の版$PSVersionTableWindows PowerShell 5.1 / PowerShell 7 系、OS 情報再現条件の切り分け、報告に必要
Format-Volume の提供元Get-Command Format-VolumeStorage モジュール、バージョン環境差(サーバー/クライアント/更新差)を把握
対象ボリュームのラベル/FSGet-Volume -DriveLetter DFileSystemLabel / FileSystem / サイズ「別ディスクだった」を防ぐ
対象ディスクの素性Get-Partition -DriveLetter D | Get-DiskDiskNumber、SerialNumber、BusType、IsSystem/IsBootOS ディスクや別 LUN の誤爆を防ぐ
対象が 1 つか(Get-Volume -DriveLetter D).Count複数返っていないか“全部”が対象になる事故を防ぐ

安全に再現・検証する方法:VHDX(仮想ディスク)で試す

「本当に -WhatIf が効かないのか」を確かめたい場合、実ディスクで試すのは危険です。Windows 標準機能の VHDX を使い、使い捨ての仮想ディスク上で検証するのが安全です。

以下は一例です(必ずテスト環境で、かつ既存ディスクを巻き込まない場所に VHDX を作成してください)。

# 1) VHDX を作成してマウント
$path = "C:\\Temp\\whatif-test.vhdx"
New-VHD -Path $path -SizeBytes 2GB -Dynamic | Out-Null
Mount-VHD -Path $path

# 2) 新規ディスクを取得して初期化→パーティション作成→ドライブレター付与

$disk = Get-Disk | Where-Object PartitionStyle -Eq 'RAW' | Sort-Object Number | Select-Object -First 1
Initialize-Disk -Number $disk.Number -PartitionStyle GPT

$part = New-Partition -DiskNumber $disk.Number -UseMaximumSize -AssignDriveLetter
$dl   = ($part | Get-Volume).DriveLetter

# 3) “WhatIf 付き”でフォーマット(※Format-Volume では WhatIf が効かない前提)

Format-Volume -DriveLetter $dl -FileSystem NTFS -NewFileSystemLabel "WhatIfTest" -WhatIf

# 4) 後片付け

Dismount-VHD -Path $path
Remove-Item -Path $path

検証が終わったら VHDX を削除し、テストの痕跡を残さないようにします。なお、上記のように “RAW ディスクを拾う” 形は誤爆しやすいので、実務ではディスク番号やファイルパスを固定し、より厳密に対象を絞り込むのが安全です。

運用での事故防止:-WhatIf を信用しない「多重防御」チェックリスト

Format-Volume のような破壊的コマンドは、ツールの安全機構だけに頼らず、運用設計で守るのが鉄則です。ここでは現場で効く“多重防御”を、具体策として整理します。

対策やること(例)効きどころ注意点
実行前の対象固定DriveLetter だけでなく DiskNumber / SerialNumber / ObjectId を控える誤爆の大半(対象取り違え)を抑止手順化しないと形骸化しやすい
二段階実行(プラン→実行)まずは「対象情報を表示するだけ」のスクリプトを実行し、目視確認後に本実行操作前の“最後の目”を増やせる自動化のスピードは落ちる
強制的な人的確認Read-Host でラベル名やディスク番号を手入力させる(コピペ禁止)コピペ事故・変数誤りに強い無人実行には向かない
実行できない状態を作るSet-Disk -IsOffline $true / -IsReadOnly $true で保護“うっかり実行”でも被害を抑える解除手順もセットで管理する
バックアップ・スナップショットVSS、ストレージスナップショット、仮想化スナップショット等最悪でも戻せる可能性が上がる復元手順の演習がないと本番で詰む

実務で使える「誤爆防止テンプレ」例

破壊的操作は、次のように “対象が 1 つであること” と “人間が再確認したこと” をコードで強制すると事故率が下がります。

param(
  [Parameter(Mandatory)]
  [ValidatePattern('^[A-Z]$')]
  [string]$DriveLetter
)

$vol = Get-Volume -DriveLetter $DriveLetter

if($null -eq $vol){
throw "指定したドライブレター $DriveLetter: が見つかりません。"
}
if(@($vol).Count -ne 1){
throw "対象ボリュームが複数検出されました。DriveLetter だけで実行しないでください。"
}

# 表示して目視確認

$vol | Select-Object DriveLetter, FileSystemLabel, FileSystem, Size, SizeRemaining | Format-List

# 追加の確認(コピペ防止のため入力させる)

$confirm = Read-Host "本当に $DriveLetter: をフォーマットするなら 'FORMAT-$DriveLetter' と入力してください"
if($confirm -ne "FORMAT-$DriveLetter"){
throw "確認文字列が一致しません。中止します。"
}

# ここで初めて実行(-WhatIf に頼らない)

Format-Volume -DriveLetter $DriveLetter -FileSystem NTFS -NewFileSystemLabel "DATA" -Force

クラスタ環境は特に危険:Get-Volume が複数返ると“全部”が対象になる

Format-Volume の公式ドキュメントには、Windows クラスタ環境で Get-Volume が返した複数のドライブが対象になり得る、という注意書きがあります。

クラスタで同じドライブレターを持つボリュームが複数見える、同名ラベルが複数存在する、CIM 経由で複数ノードの情報が返る、といった状況では「思っていた 1 本」ではなく「返ってきた全部」を処理してしまうリスクがあります。DriveLetter だけで運用しない、対象件数をコードで 1 件に縛る、この 2 つは必須です。

まず報告・改善につなげる:ドキュメントのフィードバック導線を使う

Microsoft Q&A の受け入れ回答では、挙動がバグなのか仕様なのかの切り分けとして、公式ドキュメントページ下部の「フィードバック」から状況を共有し、開発・ドキュメント側の確認につなげることが推奨されています。

実務的には、次の情報が揃っていると話が早いです。

  • 実行したコマンド全文(危険なら一部マスクしても可)
  • $PSVersionTable の出力
  • OS の版(Windows Server 2016/2019/2022/2025、Windows 10/11 など)
  • Get-Command Format-Volume の Version / Source
  • 対象がローカルディスクか、SAN/LUN か、仮想ディスクか、クラスタか

もしフォーマットしてしまったら:復旧の可能性を上げる初動

「フォーマットしてしまった。復旧できるか?」という相談は非常に多いですが、ここで重要なのは “何をするか”より先に、“何をしないか” です。フォーマット直後の操作は、復旧可能性を大きく左右します。

なお、フォーマットはデータを破壊する操作であること、GUI のディスク管理でも明確に警告されている通り、まずはバックアップが最優先です。

やってはいけないこと(復旧率を下げやすい)

  • 対象ドライブに新しいファイルを書き込む(復旧したい領域を上書きする)
  • chkdsk や最適化(デフラグ/トリム)を気軽に実行する
  • 復旧先を同じドライブにする
  • 焦って何度も“復旧ソフトを試し書き”する

まずやること(現場での基本手順)

  1. 対象ドライブの利用を止める(アプリ停止、共有停止、可能なら取り外し)
  2. 可能ならディスクをオフライン/読み取り専用にする(誤書き込み防止)
  3. バックアップ/スナップショットがあるなら、最短で復元計画を立てる
  4. 復旧作業は別ディスクへ出力する前提で進める

選択肢:Windows File Recovery(winfr)という“公式の最後の手”

バックアップが無い場合の選択肢として、Microsoft は「Windows File Recovery」というコマンドラインアプリ(winfr)を提供しています。ローカルストレージ(内蔵/外付け/USB など)から削除されたファイルの復旧を試みる用途で、Microsoft Store から入手する形です。

ただし、クラウドストレージやネットワーク共有の復旧には対応しないなど制約があります。また、復旧先は別ドライブにする必要があります。ツールを使う前に「対象ドライブを触らない」ことが最重要です。

復旧アプローチ成功しやすい条件メリットデメリット/注意
バックアップから復元定期バックアップがあり、世代管理がある最も確実で早いバックアップが無ければ不可
スナップショット/VSS/仮想化スナップショットスナップショット取得済みボリューム単位で戻せることがある取得していなければ不可、復元手順の理解が必要
Windows File Recovery(winfr)上書きが少ない、復旧先別ドライブ確保公式ツールで試せる成功保証なし、制約あり(共有/クラウド不可など)
市販/OSS の復旧ツールフォーマット形式や状況に合うツールを選べるGUI で扱いやすい場合がある誤操作で上書きリスク、無料でも万能ではない
専門業者物理障害/重要データ/高価値成功率が上がる可能性コスト・期間・機密取り扱いの確認が必要

よくある疑問:-WhatIf をこれからどう扱うべきか?

-WhatIf は信用できないの?

-WhatIf 自体が危険というより、「すべての cmdlet が WhatIf を正しく実装している」という前提が危険です。共通パラメーターは“付けられる”ことと“効く”ことが別であり、Microsoft 公式にも「共通パラメーターは利用できるが、必ずしも効果があるとは限らない」旨が説明されています。

では、破壊的コマンドの前には何をすべき?

  • ドキュメントの注記を読む(今回のように「WhatIf が動作しない」と書かれている場合がある)
  • 対象を“実体”で特定する(DriveLetter だけに依存しない)
  • テスト環境・VHDX で再現してから本番に持ち込む
  • バックアップ/スナップショットを前提に手順を作る
  • 二段階実行・人的確認・オフライン化などの多重防御を組み込む

まとめ:Format-Volume は -WhatIf 前提で運用してはいけない

  • Format-Volume は公式ドキュメント上、-WhatIf が動作しない旨の注記があるため、-WhatIf を安全装置として扱うのは危険です。
  • まずは $PSVersionTable などの環境情報を揃え、必要なら公式ドキュメントのフィードバック導線で共有すると、仕様確認やドキュメント改善につながります。
  • 破壊的操作は「対象の実体確認」「テスト環境」「バックアップ」「二段階実行」など、運用で多重防御を作るのが最も確実です。
  • 万一フォーマットした場合は、まず利用停止と上書き回避。バックアップが無い場合でも winfr などの手段はありますが、成功保証はありません。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次