1. ホーム
  2. スクリプト・コラム
  3. パワーシェル

What-ifのためのPowershellエラー処理

2022-01-04 19:47:31

自動化は利便性が高い反面、避けられないエラーも自動的に発生することがあります。そのため、Powershellには危険の防止と対処のために特別に設計されたメカニズムがあります。これらのメカニズムは、次に実行されるアクションを検証します。

試行錯誤:操作のシュミレーション

あるコマンドがどのような影響を与えるかを知りたい場合、試運転を行うことができます。このとき、Powershellはシステムに影響を与えるようなアクションを実行せず、-whatif引数でシミュレーションを実行しなかった場合の影響や結果を伝えるだけです。実際、多くのcmdltesが試運転をサポートしています。

# If you execute stop-process -name *a* it will terminate the following process.
Stop-Process -Name *a* -WhatIf
WhatIf: Execute the action "Stop-Process" on the target "AcroRd32 (4544)".
WhatIf: Executes the operation "Stop-Process" on the target "AcroRd32 (4836)".
WhatIf: The operation "Stop-Process" is executed on the target "Alipaybsm (2888)".
WhatIf: The action "Stop-Process" is performed on the target "AlipaySafeTran (2808)".
WhatIf: The operation "Stop-Process" is executed on the target "AlipaySecSvc (1656)".
WhatIf: The operation "Stop-Process" was executed on the target "AliveService (1684)".
WhatIf: The operation "Stop-Process" was executed on the target "CBGrabConnect_x64 (6052)".
WhatIf: The operation "Stop-Process" was executed on the target "FlashUtil32_11_2_202_235_ActiveX (1136)".
WhatIf: The operation "Stop-Process" was executed on the target "IAStorDataMgrSvc (2920)".
WhatIf: The operation "Stop-Process" is executed on the target "IAStorIcon (3112)".
WhatIf: The operation "Stop-Process" is executed on the target "lsass (740)".
WhatIf: The operation "Stop-Process" was executed on the target "notepad++ (5124)".
WhatIf: The operation "Stop-Process" was executed on the target "RAVCpl64 (3484)".
WhatIf: The operation "Stop-Process" is executed on the target "SearchIndexer (3788)".
WhatIf: The operation "Stop-Process" is executed on the target "taskhost (2304)".
WhatIf: The operation "Stop-Process" was executed on the target "unsecapp (264)".
WhatIf: The operation "Stop-Process" is executed on the target "unsecapp (2680)".
WhatIf: The operation "Stop-Process" is executed on the target "wlanext (1420)".
WhatIf: The operation "Stop-Process" is executed on the target "ZhuDongFangYu (1156)".

もちろん、自作のスクリプトや関数でもシミュレーションに対応させたい場合は、簡単なインテグレーションを行うだけでよい。スイッチ・パラメータを追加してください。

function MapDrive([string]$driveletter, [string]$target, [switch]$whatif)
{
  If ($whatif)
  {
    Write-Host "WhatIf: creation of a network drive " + "with the letter ${driveletter}: at destination $target"
  }
  Else
  {
    New-PSDrive $driveletter FileSystem $target
  }
}
# First run the simulation:
MapDrive k 127.0.0.1c$ -whatif
WhatIf: creation of a network drive
with letter k: at destination 127.0.0.1c$
 
# Execute the command
MapDrive k 127.0.0.1c$
Name Provider Root
---- -------- ----
k FileSystem 127.0.0.1c$

ステップバイステップの確認:クエリごとの確認

前述したように、ワイルドカード文字 "*"を使用した場合、一瞬にして多くのタスクが作成されることがあります。ミスオペレーションを発生させないためには、一つずつ確認し、一つずつ解除していくとよいでしょう。

{{コード

確認プログラムでは、6つのオプションが用意されています。

はい - 次の操作のステップにのみ進みます。
すべて はい - 操作のすべてのステップを続行します。
いいえ - このアクションをスキップして、次のアクションに進みます。
すべてではない - このアクションとそれに続くすべてのアクションをスキップします。
hang - 現在のパイプラインを一時停止し、コマンドプロンプトに戻ります。パイプラインの実行を再開するには、「exit」を入力します。
ヘルプ - ヘルプ情報を提供します。

危険な操作を自動で行う

Powershellスクリプトの開発者は、すべてのコマンドについてリスク評価を行います。例えば、Stop-Processは、現在実行中のプログラムまたはプロセスを終了させます。そのリスクファクターは中程度に設定されています。これは、通常の状況下では回復不可能で予測不可能な危険性が生じるためです。例えば、Exchangeのユーザーのメールを削除するコマンドは、メールが削除されると、そのメールのすべての内容がもはや存在しないことを意味するため、高リスクに分類されます。

powershellのデフォルト設定では、-confirmパラメータを指定しない場合でも、自動化されたアクションは危険と分類されます。この標準設定は、グローバル変数 $ConfirmPreference に格納されます。この$ConfirmPreferenceは、デフォルト設定や他の厳しい設定を判断し、対応することができます。ただし、$ConfirmPreferenceの値を "None "にすると、Powershellは、たとえリスクの高い操作であっても、操作前に確認を求めないようにします。

Stop-Process -Name *cm* -Confirm
 
Confirm
Do you really want to execute this operation?
The operation "Stop-Process" is executed on the target "cmd (1012)".
[Y] Yes (Y) [A] All Yes (A) [N] No (N) [L] All No (L) [S] Suspend (S) [?] Help (default value is "Y"): ?
Y - Continue to the next step of the operation only.
A - Continue with all steps of the operation.
N - Skip this operation and continue with the next operation.
L - Skips this operation and all subsequent operations.
S - Suspends the current pipeline and returns to the command prompt. Type "exit" to continue the pipeline.
[Y] Yes(Y) [A] All Yes(A) [N] No(N) [L] All No(L) [S] Suspend(S) [?] Help (default value is "Y"): N
 
Confirm
Do you really want to perform this operation?
Execute the operation "Stop-Process" on the target "cmd (3704)".
[Y] Yes (Y) [A] All Yes (A) [N] No (N) [L] All No (L) [S] Suspend (S) [?] Help (default value is "Y"): s
PS E:>>>
PS E:>>> exit
 
Confirm
Do you really want to perform this operation?
Execute the operation "Stop-Process" on the target "cmd (3704)".
[Y] Yes(Y) [A] All Yes(A) [N] No(N) [L] All No(L) [S] Suspend(S) [?] Help (default value is "Y"): y
 
Confirm
Do you really want to perform this operation?
Execute the operation "Stop-Process" on the target "cmd (4404)".
[Y] Yes (Y) [A] All Yes (A) [N] No (N) [L] All No (L) [S] Suspend (S) [?] Help (default value is "Y"): a

要約すると という2つのケースを想定しています。

危険な環境 実行する操作の危険性がわからない場合は、$ConfirmPreferenceをlowに設定すると、少しは安全です。
/{br 安全な環境 特定の状況で安全でない操作を多く行う場合、コマンドごとに-confirmをfalseにするのは面倒なので、$ConfirmPreferenceをNoneにすると便利です。ただし、分散化のリスクを最小限にするため、スクリプト内で $ConfirmPreference を "None" に設定することをお勧めします。