複数のファイルへ処理をかける前に、どこが変更対象になるかを見たい。PowerShellの対応するコマンドでは、-WhatIfで変更予定の表示を確認できます。コピー先のパスを取り違えていないか、実際にコピーする前に確認するための機能です。
ただし、すべての処理を自動で止める万能の試運転ではありません。使うコマンドがWhatIfへ対応しているかと、スクリプトの中で別の処理が実行されていないかを確認します。
コピーを予告表示する例
次は練習用の新しい一時フォルダーで、コピーの前後を比べる例です。最初に作るのは小さな入力ファイルだけです。既存ファイルは指定しません。
$practiceDir = Join-Path ([IO.Path]::GetTempPath()) ('whatif-' + [guid]::NewGuid())
[IO.Directory]::CreateDirectory($practiceDir) | Out-Null
$sourceFile = Join-Path $practiceDir 'source.txt'
$targetFile = Join-Path $practiceDir 'target.txt'
Set-Content -LiteralPath $sourceFile -Value 'practice' -Encoding UTF8
Copy-Item -LiteralPath $sourceFile -Destination $targetFile -WhatIf
Test-Path -LiteralPath $targetFile
Copy-Item -LiteralPath $sourceFile -Destination $targetFile
Test-Path -LiteralPath $targetFile
-WhatIf付きの操作の後では、コピー先の存在確認はFalseです。その次の、-WhatIfを付けない実際のコピーの後はTrueになります。表示された変更予定だけでなく、ファイルがあるかも確認すると、試運転と実処理の違いをつかめます。
入力ファイルを用意するSet-ContentはCopy-Item -WhatIfとは別に実行されています。コピーに試運転を付けたから、それより前の処理まで実行されなかった、とは考えないようにしてください。
対応する処理の範囲
WhatIfは、PowerShellのShouldProcessへ対応した処理で使われます。自作の関数に引数の名前だけを追加しても、実際の書き込みが止まるわけではありません。何を変更する直前に確認し、どの操作を実行しないようにするかという実装が必要です。
また、スクリプトが外部のPythonや実行ファイルを起動する場合、その先の書き込みが自動で試運転になる保証もありません。.NETのメソッドで直接ファイルを書き込む処理も、別に制御する必要があります。画面に「試運転」と出たかだけで判断しないようにします。
表示された予定を読む
コピー元、コピー先、対象件数、上書きの可能性を確認します。パターンで複数ファイルを指定しているなら、想定していないファイルまで含まれていないかも見ます。確認のために、対象一覧を先に読み取りだけで出す方法も使えます。
試運転を通ったからといって、その後の実行成功が保証されるわけではありません。実行時点の権限、空き容量、ファイルの使用状態などは変わり得ます。実処理後に、出力の件数や内容を読み戻す確認も残します。
まず一件で前後を比べる
大量のファイルへ適用する前に、この例のような一件で、試運転と実処理の結果を見比べます。試運転でファイルが増えていないことと、実処理で意図した一件だけが作られたことを、両方確かめてください。
ここではWindows PowerShell 5.1とPowerShell 7で、練習用コピーの存在確認までを試します。実際の一括整理や削除は行いません。-WhatIfを使う場合も、変更対象の控えと、実行後の照合は別の手順として用意します。
関連する記事
公式資料
Everything you wanted to know about ShouldProcess – PowerShell | Microsoft Learn
Copy-Item (Microsoft.PowerShell.Management) – PowerShell | Microsoft Learn
