トピック about_Debuggers 簡易説明 Windows PowerShell デバッガーについて説明します。 詳細説明 デバッグとは、スクリプトの命令にあるエラーを識別および修正するためにスクリプトの実行中に スクリプトを検査するプロセスです。Windows PowerShell デバッガーは、スクリプト内のエラーお よび無効性の検査および識別を支援するように設計されています。 注: Windows PowerShell デバッガーはリモートでは実行されません。リモート コンピューターでス クリプトをデバッグするには、スクリプトをローカル コンピューターにコピーします。 Windows PowerShell デバッガーの機能を使用して、Windows PowerShell のスクリプト、関数、コマンド、 または式を実行中に検査することができます。Windows PowerShell デバッガーには、ブレークポイントの 設定と管理、およびコール スタックの表示を行うことができる一連のコマンドレットが含まれています。 Windows PowerShell には、スクリプト、関数、およびコマンドのデバッグに使用できるいくつか の方法があります。 方法 1: Set-PsDebug コマンドレットは、ステップ処理およびトレースを含む基本的なスクリプト のデバッグ機能を提供します。詳細については、次のように入力してヘルプを参照してください。 "get-help set-psdebug". 方法 2: Set-StrictMode コマンドレットを使用して、初期化されていない変数への参照、オブジェクトに 存在しないプロパティへの参照、および無効な関数構文を検出します。 方法 3: 変数の値を表示するステートメント、コマンド ラインからの入力を読み取るステートメン ト、または現在の命令を報告するステートメントなどの診断ステートメントをスクリプトに追加しま す。このタスクには、Write-Host、Write-Debug、Write-Warning、Write-Verbose などの動 詞 Write を含むコマンドレットを使用します。 方法 4: Windows PowerShell デバッガーを使用して、スクリプトをデバッグします。または、デバッ ガーを使用して、コマンド プロンプトで入力した関数またはスクリプト ブロックをデバッグします。 ブレークポイントの設定、スクリプトのステップ スルー、変数の値の確認、診断コマンドおよびログ コマンドの実行、およびコール スタックの表示が可能です。 デバッガー コマンドレット Windows PowerShell デバッガーには、以下の一連のコマンドレットがあります。 Set-PsBreakpoint: 行、変数、およびコマンドにブレークポイントを設定します。 Get-PsBreakpoint: 現在のセッションのブレークポイントを取得します。 Disable-PsBreakpoint: 現在のセッションのブレークポイントを無効にします。 Enable-PsBreakpoint: 現在のセッションのブレークポイントを再び有効にします。 Remove-PsBreakpoint: 現在のセッションからブレークポイントを削除します。 Get-PsCallStack: 現在のコール スタックを表示します。 デバッガーの開始および停止 デバッガーを開始するには、1 つまたは複数のブレークポイントを設定します。その後、デバッグ するスクリプト、コマンド、または関数を実行します。 ブレークポイントに到達すると、実行が停止し、デバッガーに制御が渡されます。 デバッガーを停止するには、スクリプト、コマンド、または関数を完了するまで実行します。または、 「stop」または「t」と入力します。 デバッガー コマンド Windows PowerShell コンソールでデバッガーを使用するときは、以下のコマンドを使用して実 行を制御します。 注: その他のホスト アプリケーションでデバッガーを使用する方法については、ホスト アプリケ ーションのドキュメントを参照してください。 s, Step-into 次のステートメントを実行してから停止します。 v, Step-over 次のステートメントを実行しますが、関数および呼び出しをス キップします。スキップしたステートメントは実行されますが、 ステップ スルーされません。 o, Step-out 現在の関数からステップ アウトします。入れ子になっている場 合、1 つ上のレベルにステップ アップします。本文にある場合、 最後または次のブレークポイントまで進みます。スキップした ステートメントは実行されますが、ステップ スルーされません。 c, Continue スクリプトが完了するまで、または次のブレークポイントに到達 するまで続行します。スキップしたステートメントは実行されま すが、ステップ スルーされません。 l, List スクリプト内の、実行中の部分を表示します。既定では、現在の行、 前の 5 行、および次の 10 行を表示します。スクリプトの一覧表示 を続行するには、Enter キーを押します。 l <m>, List <m> で指定された行番号で始まる 16 行のスクリプトを表示 します。 l <m> <n>, List <m> で指定された行番号で始まる <n> 行のスクリプトを表示します。 q, Stop スクリプトの実行を停止し、デバッガーを終了します。 k, Get-PsCallStack 現在のコール スタックを表示します。 <Enter> 最後のコマンドが Step (s)、Step-over (v)、または List (l) だった 場合は、そのコマンドを繰り返します。それ以外の場合は、送信操作を表します。 ?, h デバッガー コマンドのヘルプを表示します。 デバッガーを終了するには、Stop (q) を使用します。 デバッガーの実行中でも、コマンドの入力、変数の値の表示、コマンドレットの使用、およびスクリプトの実行が可能です。 これらのデバッガー コマンドを使用することにより、スクリプトを実行し、問題の場所で停止 し、変数の値およびシステムの状態を検査して、問題を特定するまでスクリプトの実行を続行するこ とができます。 デバッガー環境 ブレークポイントに到達すると、デバッガー環境に入ります。コマンド プロンプトが、"[DBG]:" で始まるように変更されます。このプロンプトはカスタマイズすることができます。 また、Windows PowerShell コンソールなど一部のホスト アプリケーション (ただし Windows PowerShell Integrated Scripting Environment (ISE) を除く) では、入れ子になったプロンプ トがデバッグ用に開きます。コマンド プロンプトに表示される大なり文字 (ASCII 62) の繰り 返しで、入れ子になったプロンプトを確認できます。 たとえば、以下は Windows PowerShell コンソールの既定のデバッグ プロンプトです。 [DBG]: PS (get-location)>>> $NestedPromptLevel 自動変数を使用することによって入れ子のレベルを確認できます。 また、自動変数 $PSDebugContext は、ローカル スコープで定義されています。 $PSDebugContext 変数の有無を利用すると、デバッガー内であるかどうかを判断できます。 次にその例を示します。 if ($psdebugcontext) {"Debugging"} else {"Not Debugging"} デバッグ中に、$PSDebugContext 変数の値を使用できます。 [DBG]: PS>>> $psdebugcontext.invocationinfo Name CommandLineParameters UnboundArguments Location ---- --------------------- ---------------- -------- = {} {} C:\ps-test\vote.ps1 (1) デバッグおよびスコープ デバッガーに割り込んでも処理中のスコープは変更されませんが、スクリプトのブレークポイント に到達すると、そのスクリプト スコープに移動します。スクリプト スコープは、デバッガーを実 行したスコープの子です。 スクリプト スコープで定義される変数およびエイリアスを確認するには、Scope パラメーターの Get-Alias または Get-Variable コマンドレットを使用します。 たとえば、次のコマンドはローカル (スクリプト) スコープの変数を取得します。 get-variable -scope 0 このコマンドは次のように短縮することができます。 gv -s 0 この方法は、スクリプト内で定義した変数およびデバッグ中に定義した変数のみを確認するときに便利です。 コマンド ラインでのデバッグ 変数のブレークポイントまたはコマンドのブレークポイントを設定する場合、ブレークポイントは スクリプト ファイル内にのみ設定できます。ただし既定では、ブレークポイントは現在のセッショ ンで実行される任意のものに設定されます。 たとえば、$name 変数にブレークポイントを設定した場合、ブレークポイントを無効にするか削除 するまで、デバッガーでは、実行するスクリプト、コマンド、関数、スクリプトのコマンドレットま たは式の中にある任意の $name 変数で実行が中断されます。 これによって、スクリプトをより実際的なコンテキストでデバッグできますが、そのコンテキストでは、 スクリプトはセッションにあるおよびユーザーのプロファイルにある関数、変数、およびその他の スクリプトによって影響を受ける可能性があります。 行のブレークポイントは、スクリプト ファイルに固有のため、スクリプト ファイル内のみ設定さ れます。 関数のデバッグ Begin、Process、および End セクションがある関数でブレークポイントを設定すると、デバッガー は各セクションの最初の行で実行を中断します。 次にその例を示します。 function test-cmdlet { begin { write-output "Begin" } process { write-output "Process" } end { write-output "End" } } C:\PS> set-psbreakpoint -command test-cmdlet C:\PS> test-cmdlet Begin デバッグ モードを開始します。ヘルプを表示するには、h または ? を使用してください。 ヒット 'prompt:test-cmdlet' のコマンドのブレークポイント test-cmdlet [DBG]: C:\PS> c Process デバッグ モードを開始します。ヘルプを表示するには、h または ? を使用してください。 ヒット 'prompt:test-cmdlet' のコマンドのブレークポイント test-cmdlet [DBG]: C:\PS> c End デバッグ モードを開始します。ヘルプを表示するには、h または ? を使用してください。 ヒット 'prompt:test-cmdlet' のコマンドのブレークポイント test-cmdlet [DBG]: C:\PS> リモート スクリプトのデバッグ Windows PowerShell デバッガーはリモート セッションでは実行できません。リモート コンピュ ーターでスクリプトをデバッグするには、スクリプトをローカル コンピューターにコピーします。 次のコマンドは、Test.ps1 スクリプトを Server01 リモート コンピューターからローカル コンピ ューターにコピーします。 invoke-command -computername Server01 ` {get-content c:\ps-test\test.ps1} | set-location c:\ps-test\test.ps1 例 このテスト スクリプトは、オペレーティング システムのバージョンを検出し、システムに適した メッセージを表示します。関数、関数呼び出し、および変数が含まれます。 次のコマンドは、テスト スクリプト ファイルの内容を表示します。 c:>\PS-test> get-content test.ps1 function psversion { "Windows Powershell " + $psversiontable.psversion if ($psversiontable.psversion.major -lt 2) { "Upgrade to Windows PowerShell 2.0!" } else { "Have you run a background job today (start-job)?" } } $scriptname = $MyInvocation.MyCommand.Path psversion "Done $scriptname." 起動するには、スクリプト内の行、コマンド、変数、関数などの目的の場所にブレークポイントを設定します。 現在のディレクトリの Test.ps1 スクリプトの最初の行に、行のブレークポイントを作成することに よって起動します。 PS C:\ps-test> set-psbreakpoint -line 1 -script test.ps1 このコマンドは次のように短縮することができます。 PS C:\ps-test> spb 1 -s test.ps1 このコマンドは、行のブレークポイント オブジェクト (System.Management.Automation.LineBreakpoint) を返します。 Column : 0 Line : 1 Action : Enabled : True HitCount : 0 Id : 0 Script : C:\ps-test\test.ps1 ScriptName : C:\ps-test\test.ps1 ここで、スクリプトを起動します。 PS C:\ps-test> .\test.ps1 スクリプトが最初のブレークポイントに到達すると、ブレークポイント メッセージによりデバッ ガーがアクティブであることが示されます。メッセージには、ブレークポイントの説明とスクリプト の最初の行にある関数宣言のプレビューが表示されます。また、デバッガーに制御があることを示す コマンド プロンプトに変更されます。 プレビュー行には、スクリプト名とプレビューしているコマンドの行番号が含まれます。 デバッグ モードを開始します。ヘルプを表示するには、h または ? を使用してください。 ヒット 'C:\ps-test\test.ps1:1' の行のブレークポイント test.ps1:1 function psversion { DBG> Step コマンド (s) を使用してスクリプトの最初のステートメントを実行し、次のステートメントを プレビューします。次のステートメントは、$MyInvocation 自動変数を使用して $ScriptName 変数の値をスクリプト ファイルのパスおよびファイル名に設定します。 DBG> s test.ps1:11 $scriptname = $MyInvocation.MyCommand.Path この時点では $ScriptName 変数に値が設定されませんが、その値を表示することで変数の値を確認 することができます。この場合、値は $null です。 DBG> $scriptname DBG> 別の Step コマンド (s) を使用して現在のステートメントを実行し、スクリプトの次のステー トメントをプレビューします。次のステートメントは、PsVersion 関数を呼び出します。 DBG> s test.ps1:12 psversion この時点で $ScriptName 変数に値が設定されますが、その値を表示することで変数の値を確認する ことができます。この場合、値はスクリプトのパスに設定されます。 DBG> $scriptname C:\ps-test\test.ps1 別の Step コマンドを使用して関数呼び出しを実行します。Enter キーを押すか、Step の「s」と 入力します。 DBG> s test.ps1:2 "Windows Powershell " + $psversiontable.psversion デバッグ メッセージには、関数にあるステートメントのプレビューが含まれます。 このステートメントを実行し、関数にある次のステートメントをプレビューする場合、Step コマ ンドを使用することができます。ただし、ここでは Step-Out コマンド (o) を使用します。関数の 実行を完了し (ブレークポイントに到達した場合を除く)、スクリプトの次のステートメントに進み ます。 DBG> o Windows Powershell 2.0 Have you run a background job today (start-job)? test.ps1:13 "Done $scriptname" スクリプトの最後のステートメントにいるため、Step、Step-Out、および Continue コマンドの結 果は同じになります。ここでは Step-Out コマンド (o) を使用します。 Done C:\ps-test\test.ps1 PS C:\ps-test> Step-Out コマンドは最後のコマンドを実行します。標準のコマンド プロンプトによって、デバ ッガーが終了し、制御をコマンド プロセッサに返したことが示されます。 ここで、デバッガーを再び実行します。まず、現在のブレークポイントを削除するには、Get- PsBreakpoint および Remove-PsBreakpoint コマンドレットを使用します。 (ブレークポイントの再利用を考えている場合は、Remove-PsBreakpoint コマンドレットではな く Disable-PsBreakpoint を使用します。) PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint このコマンドは次のように短縮することができます。 PS C:\ps-test> gbp | rbp または、次の関数ような関数を記述することによってコマンドを実行します。 function delbr { gbp | rbp } ここで、$scriptname 変数にブレークポイントを作成します。 PS C:\ps-test> set-psbreakpoint -variable scriptname -script test.ps1 このコマンドは次のように短縮することができます。 PS C:\ps-test> sbp -v scriptname -s test.ps1 ここで、スクリプトを起動します。スクリプトは、変数のブレークポイントに到達します。既定モ ードは Write なので、実行は変数の値を変更するステートメントの直前で停止します。 PS C:\ps-test> .\test.ps1 ヒット 'C:\ps-test\test.ps1:$scriptname' の変数のブレークポイント (Write アクセス) test.ps1:11 $scriptname = $MyInvocation.mycommand.path DBG> $scriptname 変数の現在の値、$null を表示します。 DBG> $scriptname DBG> Step コマンド (s) を使用して変数に値を設定するステートメントを実行します。その後、 $scriptname 変数の新しい値を表示します。 DBG> $scriptname C:\ps-test\test.ps1 Step コマンド (s) を使用してスクリプトの次のステートメントをプレビューします。 DBG> s test.ps1:12 psversion 次のステートメントは、PsVersion 関数に対する呼び出しです。関数をスキップしながらも実行する には、Step-Over コマンド (v) を使用します。Step-Over を使用する際に既に関数内に入って いる場合、その関数は無効になります。関数呼び出しは表示されますが、実行されません。 DBG> v Windows Powershell 2.0 Have you run a background job today (start-job)? test.ps1:13 "Done $scriptname" Step-Over コマンドは関数を実行し、スクリプトの次のステートメントをプレビューして、この 最後の行を出力します。 Stop コマンド (t) を使用してデバッガーを終了します。コマンド プロンプトは標準のコマンド プロンプトに戻ります。 C:\ps-test> ブレークポイントを削除するには、Get-PsBreakpoint および Remove-PsBreakpoint コマン ドレットを使用します。 PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint PsVersion 関数に新しいコマンドのブレークポイントを作成します。 PS C:\ps-test> Set-PsBreakpoint -command psversion -script test.ps1 このコマンドは次のように短縮することができます。 PS C:\ps-test> sbp -c psversion -s test.ps1 ここで、スクリプトを実行します。 PS C:\ps-test> .\test.ps1 ヒット 'C:\ps-test\test.ps1:psversion' のコマンドのブレークポイント test.ps1:12 psversion DBG> スクリプトは関数呼び出しでブレークポイントに到達します。この時点で、関数 はまだ呼び出されていません。これによって、Set-PsBreakpoint の Action パラメー ターを使用して、ブレークポイントの実行条件を設定したり、ログの起動、診断または セキュリティ スクリプトの起動などの前処理タスクまたは診断タスクを実行したりす ることができます。 アクションを設定するには、Continue コマンド (c) を使用してスクリプトを終了し、Remove- PsBreakpoint コマンドを使用して現在のブレークポイントを削除します (ブレークポイントは 読み取り専用のため、現在のブレークポイントにアクションを追加することはできません)。 DBG> c Windows PowerShell 2.0 Have you run a background job today (start-job)? Done C:\ps-test\test.ps1 PS C:\ps-test> get-psbreakpoint | remove-psbreakpoint PS C:\ps-test> ここで、アクションを指定した新しいコマンドのブレークポイントを作成します。次のコマンド は、関数を呼び出すと $scriptname 変数の値をログに記録するアクションを指定したコマンドのブレ ークポイントを設定します。アクションに Break キーワードが使用されていないため、実行は停止し ません (バッククォート記号 (`) は行連結文字です)。 PS C:\ps-test> set-psbreakpoint -command psversion -script test.ps1 ` -action { add-content "The value of `$scriptname is $scriptname." ` -path action.log} ブレークポイントの条件を設定するアクションを追加することもできます。次のコマンドでは、実 行ポリシーが RemoteSigned に設定されている場合にのみ、コマンドのブレークポイントが実行され ます。RemoteSigned は、スクリプトの実行を許可する最も制限の厳しいポリシーです (バッククォ ート記号 (`) は連結文字です)。 PS C:\ps-test> set-psbreakpoint -script test.ps1 -command psversion ` -action { if ((get-executionpolicy) -eq "RemoteSigned") { break }} このアクションの Break キーワードは、ブレークポイントを実行するようにデバッガーに指示しま す。Continue キーワードを使用して、中断せずに実行するようにデバッガーに指示することもできま す。既定のキーワードは Continue であるため、実行を停止するには Break を指定する必要があり ます。 ここで、スクリプトを実行します。 PS C:\ps-test> .\test.ps1 ヒット 'C:\ps-test\test.ps1:psversion' のコマンドのブレークポイント test.ps1:12 psversion 実行ポリシーは RemoteSigned に設定されているため、実行は関数呼び出しで停止します。 この時点で、コール スタックの確認が必要になる場合もあります。Get-PsCallStack コマンド レットまたは Get-PsCallStack デバッガー コマンド (k) を使用します。 次のコマンドは、現在のコール スタックを取得します。 DBG> k 2: prompt 1: .\test.ps1: $args=[] 0: prompt: $args=[] この例では、Windows PowerShell デバッガーを使用する多くの方法のうちの一部のみを示します。 デバッガーのコマンドレットの詳細については、次のコマンドを入力してください。 help <cmdlet-name> -full たとえば、次のように入力します。 help set-psbreakpoint -full 関連項目 Disable-PsBreakpoint Get-PsBreakpoint Remove-PsBreakpoint Set-PsBreakpoint Set-PsDebug Set-Strictmode Write-Debug Write-Verbose Enable-PsBreakpoint Get-PsCallStack