ja-JP/about_Debuggers.help.txt

TOPIC
    about_Debuggers

簡単な説明
    PowerShell デバッガーについて説明します。

詳細な説明
    デバッグとは、スクリプトの命令の誤りを特定して修正するために、実行中の
    スクリプトを調べるプロセスです。PowerShell デバッガーは、スクリプト、
    関数、コマンド、PowerShell Desired State Configuration (DSC) 構成、または
    式の中の誤りや非効率な部分を調べて特定するのに役立ちます。

    PowerShell 5.0 以降、PowerShell デバッガーは、コンソールまたは Windows
    PowerShell Integrated Scripting Environment (ISE) のいずれかでリモート
    コンピューター上で実行されているスクリプト、関数、コマンド、構成、または
    式をデバッグできるように更新されました。

    メモ: Windows PowerShell ISE は Windows PowerShell のみをサポートします。
    PowerShell 6 以降では、PowerShell 拡張機能を備えた Visual Studio Code を
    使用する必要があります。詳細については「Visual Studio Code でのデバッグ」
    を参照してください。

デバッガーのコマンドレット
    PowerShell デバッガーには、次のコマンドレットのセットが含まれています。

    - Set-PSBreakpoint: 行、変数、コマンドにブレークポイントを設定します。
    - Get-PSBreakpoint: 現在のセッションのブレークポイントを取得します。
    - Disable-PSBreakpoint: 現在のセッションのブレークポイントを無効にします。
    - Enable-PSBreakpoint: 現在のセッションのブレークポイントを再度有効に
      します。
    - Remove-PSBreakpoint: 現在のセッションからブレークポイントを削除します。
    - Get-PSCallStack: 現在の呼び出し履歴を表示します。

デバッガーの開始と停止
    デバッガーを開始するには、1 つ以上のブレークポイントを設定し、デバッグ
    するスクリプト、コマンド、または関数を実行します。

    ブレークポイントに到達すると、実行が停止し、制御がデバッガーに渡されます。

    デバッガーを停止するには、スクリプト、コマンド、または関数を完了するまで
    実行します。あるいは、stop または t と入力します。

デバッガーのコマンド
    PowerShell コンソールでデバッガーを使用する場合は、次のコマンドを使って
    実行を制御します。Windows PowerShell ISE では、Debug メニューのコマンドを
    使用します。

    メモ: 他のホストアプリケーションでデバッガーを使う方法については、その
    ホストアプリケーションのドキュメントを参照してください。

    - s、StepInto: 次のステートメントを実行してから停止します。

    - v、StepOver: 次のステートメントを実行しますが、関数や呼び出しはスキップ
      します。スキップされたステートメントは実行されますが、ステップ実行は
      されません。

    - Ctrl+Break: (ISE では Break All) PowerShell コンソールまたは Windows
      PowerShell ISE のいずれかで実行中のスクリプトに割り込みます。Windows
      PowerShell 2.0、3.0、4.0 では Ctrl+Break はプログラムを閉じる点に注意
      してください。Break All は、ローカルとリモートの両方で対話的に実行中の
      スクリプトに対して機能します。

    - o、StepOut: 現在の関数からステップアウトします。入れ子の場合は 1 つ上の
      レベルに戻ります。メイン本体にいる場合は、終了または次のブレークポイント
      まで続行します。スキップされたステートメントは実行されますが、ステップ
      実行はされません。

    - c、Continue: スクリプトが完了するか、次のブレークポイントに到達するまで
      実行を続けます。スキップされたステートメントは実行されますが、ステップ
      実行はされません。

    - l、List: 実行中のスクリプトの部分を表示します。既定では、現在の行、その
      前の 5 行、後続の 10 行を表示します。スクリプトの表示を続けるには ENTER
      キーを押します。

    - l <m>、List: <m> で指定された行番号から始まるスクリプトの 16 行を表示
      します。

    - l <m> <n>、List: <m> で指定された行番号から始まるスクリプトの <n> 行を
      表示します。

    - q、Stop、Exit: スクリプトの実行を停止し、デバッガーを終了します。
      Debug-Job コマンドレットを実行してジョブをデバッグしている場合、Exit
      コマンドはデバッガーを切り離し、ジョブの実行を続行させます。

    - k、Get-PSCallStack: 現在の呼び出し履歴を表示します。

    - <Enter>: 最後のコマンドが Step (s)、StepOver (v)、List (l) のいずれか
      であった場合、それを繰り返します。それ以外の場合は、送信操作を表します。

    - ?、h: デバッガーコマンドのヘルプを表示します。

    デバッガーを終了するには、Stop (q) を使用できます。

    PowerShell 5.0 以降では、Debug-Job または Debug-Runspace のいずれかを実行
    して開始した入れ子のデバッグセッションを終了するために、Exit コマンドを
    実行できます。

    これらのデバッガーコマンドを使うと、スクリプトを実行し、注目する箇所で
    停止して、変数の値やシステムの状態を調べ、問題を特定するまでスクリプトの
    実行を続けることができます。

    メモ: > などのリダイレクト演算子を含むステートメントにステップインすると、
    PowerShell デバッガーはスクリプト内の残りのすべてのステートメントを
    ステップオーバーします。

スクリプト変数の値の表示
    デバッガー内にいる間は、コマンドを入力したり、変数の値を表示したり、
    コマンドレットを使用したり、コマンドラインでスクリプトを実行したりする
    こともできます。デバッグ中のスクリプト内のすべての変数の現在の値を表示
    できますが、次の自動変数は例外です。

        $_
        $args
        $input
        $MyInvocation
        $PSBoundParameters

    これらの変数のいずれかの値を表示すると、スクリプト内の変数の値ではなく、
    デバッガーが使用する内部パイプラインのその変数の値が得られます。

    デバッグ中のスクリプトについてこれらの変数の値を表示するには、これらの値
    を新しい変数に保存する行をスクリプトに追加します。これらの新しい行の後に
    ブレークポイントを設定します。その後、新しい変数の値を表示できます。

    例:

        $scriptArgs = $args
        $scriptname = $MyInvocation.PSCommandPath

デバッガーの環境
    ブレークポイントに到達すると、デバッガー環境に入ります。コマンドプロンプト
    が変わり、"[DBG]:" で始まるようになります。また、PowerShell コンソールの
    ような一部のホストアプリケーションでは、デバッグ用に入れ子のプロンプトが
    開きます。入れ子のプロンプトは、コマンドプロンプトに表示される繰り返しの
    大なり記号 (ASCII 62) によって判別できます。

    プロンプトのカスタマイズの詳細については about_Prompts を参照してください。

    入れ子のレベルは $NestedPromptLevel 自動変数を使って確認できます。自動
    変数 $PSDebugContext はローカルスコープで定義されます。$PSDebugContext
    変数の存在を利用して、デバッガー内で実行しているかどうかを判別できます。

    例:

        if ($PSDebugContext) {"Debugging"} else {"Not Debugging"}

    $PSDebugContext 変数の値をデバッグに使用できます。

        [DBG]: PS>>> $PSDebugContext.InvocationInfo

        Name CommandLineParameters UnboundArguments Location
        ---- --------------------- ---------------- --------
        = {} {} C:\ps-test\vote.ps1 (1)

デバッグとスコープ
    デバッガーに割り込んでも、操作しているスコープは変わりませんが、スクリプト
    内のブレークポイントに到達すると、スクリプトスコープに移動します。スクリプ
    トスコープは、デバッガーを実行したスコープの子です。

    スクリプトスコープで定義されている変数やエイリアスを見つけるには、
    Get-Alias または Get-Variable コマンドレットの Scope パラメーターを使用
    します。

    たとえば、次のコマンドはローカル (スクリプト) スコープの変数を取得します。

        Get-Variable -Scope 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
        Entering debug mode. Use h or ? for help.

        Hit Command breakpoint on 'prompt:Test-Cmdlet'

        Test-Cmdlet

        [DBG]: C:\PS> c
        Process
        Entering debug mode. Use h or ? for help.

        Hit Command breakpoint on 'prompt:Test-Cmdlet'

        Test-Cmdlet

        [DBG]: C:\PS> c
        End
        Entering debug mode. Use h or ? for help.

        Hit Command breakpoint on 'prompt:Test-Cmdlet'

        Test-Cmdlet

        [DBG]: C:\PS>

リモートスクリプトのデバッグ
    Enter-PSSession を実行すると、対話的なリモート PowerShell セッションを
    開始できます。そこでは、リモートコンピューター上のスクリプトファイルや
    コマンドにブレークポイントを設定してデバッグできます。Enter-PSSession を
    使うと、リモートコンピューターでスクリプトやコマンドを実行している切断
    されたセッションに再接続できます。実行中のスクリプトがブレークポイントに
    到達すると、クライアントセッションは自動的にデバッガーを開始します。
    スクリプトを実行している切断されたセッションがすでにブレークポイントに
    到達している場合、セッションに再接続すると Enter-PSSession は自動的に
    コマンドラインデバッガーを開始します。

    次の例はこの動作を示しています。ブレークポイントはスクリプトの 6、11、22、
    25 行目に設定されています。デバッガーが開始されると、プロンプトには 2 つの
    識別可能な変化が現れます。

    - セッションが実行されているコンピューターの名前
    - デバッグモードであることを知らせる DBG プロンプト

        Enter-PSSession -Cn localhost
        [localhost]: PS C:\psscripts> Set-PSBreakpoint .\ttest19.ps1 6, 11, 22, 25

        ID Script Line Command Variable Action
        -- ------ ---- ------- -------- ------
        0 ttest19.ps1 6
        1 ttest19.ps1 11
        2 ttest19.ps1 22
        3 ttest19.ps1 25

        [localhost]: PS C:\psscripts> .\ttest19.ps1
        Hit Line breakpoint on 'C:\psscripts\ttest19.ps1:11'

        At C:\psscripts\ttest19.ps1:11 char:1
        + $winRMName = "WinRM"
        # + ~

        [localhost]: [DBG]: PS C:\psscripts>> list

        6: 1..5 | foreach { sleep 1; Write-Output "hello2day $_" }
        7: }
        # 8:

        9: $count = 10
        10: $psName = "PowerShell"
        11:* $winRMName = "WinRM"
        12: $myVar = 102
        # 13:

        14: for ($i=0; $i -lt $count; $i++)
        15: {
        16: sleep 1
        17: Write-Output "Loop iteration is: $i"
        18: Write-Output "MyVar is $myVar"
        # 19:

        20: hello2day
        # 21:


        [localhost]: [DBG]: PS C:\psscripts>> stepover
        At C:\psscripts\ttest19.ps1:12 char:1
        + $myVar = 102
        # + ~

        [localhost]: [DBG]: PS C:\psscripts>> quit
        [localhost]: PS C:\psscripts> Exit-PSSession
        PS C:\psscripts>


    このテストスクリプトは、PowerShell のバージョンを検出し、バージョンに
    応じたメッセージを表示します。このスクリプトには、関数、関数呼び出し、
    変数が含まれています。

    次のコマンドは、テストスクリプトファイルの内容を表示します。

        PS C:\PS-test> Get-Content test.ps1

        function psversion {
          "PowerShell " + $PSVersionTable.PSVersion
          if ($PSVersionTable.PSVersion.Major -lt 7) {
            "Upgrade to PowerShell 7!"
          }
          else {
            "Have you run a background job today (Start-Job)?"
          }
        }

        $scriptName = $MyInvocation.PSCommandPath
        psversion
        "Done $scriptName."

    まず、行、コマンド、変数、関数など、スクリプト内の注目する箇所に
    ブレークポイントを設定します。

    最初に、現在のディレクトリにある Test.ps1 スクリプトの 1 行目に行ブレーク
    ポイントを作成します。

        PS C:\ps-test> Set-PSBreakpoint -Line 1 -Script 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

    スクリプトが最初のブレークポイントに到達すると、ブレークポイントメッセージ
    がデバッガーがアクティブであることを示します。そのメッセージはブレーク
    ポイントについて記述し、スクリプトの最初の行 (関数宣言) をプレビュー表示
    します。また、コマンドプロンプトも変わり、デバッガーが制御を持っている
    ことを示します。

    プレビュー行には、スクリプト名とプレビューされたコマンドの行番号が含まれ
    ます。

        Entering debug mode. Use h or ? for help.

        Hit Line breakpoint on 'C:\ps-test\test.ps1:1'

        test.ps1:1 function psversion {
        DBG>

    Step コマンド (s) を使って、スクリプトの最初のステートメントを実行し、次の
    ステートメントをプレビュー表示します。次のステートメントは、$MyInvocation
    自動変数を使って、$scriptName 変数の値をスクリプトファイルのパスとファイル
    名に設定します。

        DBG> s
        test.ps1:11 $scriptName = $MyInvocation.PSCommandPath

    この時点では $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 "PowerShell " + $PSVersionTable.PSVersion

    デバッグメッセージには、関数内のステートメントのプレビューが含まれます。
    このステートメントを実行して関数内の次のステートメントをプレビュー表示
    するには Step コマンドを使用できますが、この場合は StepOut コマンド (o) を
    使用します。これは (ブレークポイントに到達しない限り) 関数の実行を完了し、
    スクリプト内の次のステートメントにステップします。

        DBG> o
        Windows PowerShell 2.0
        Have you run a background job today (Start-Job)?
        test.ps1:13 "Done $scriptName"

    スクリプトの最後のステートメントにいるため、Step、StepOut、Continue の各
    コマンドは同じ効果になります。この場合は StepOut (o) を使用します。

        Done C:\ps-test\test.ps1
        PS C:\ps-test>

    StepOut コマンドは最後のコマンドを実行します。標準のコマンドプロンプトは、
    デバッガーが終了し、制御をコマンドプロセッサに戻したことを示します。

    次に、もう一度デバッガーを実行します。まず、現在のブレークポイントを削除
    するために 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
        Hit Variable breakpoint on 'C:\ps-test\test.ps1:$scriptName'
        (Write access)

        test.ps1:11 $scriptName = $MyInvocation.PSCommandPath
        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 関数の呼び出しです。関数をスキップしつつ、
    それでも実行するには StepOver コマンド (v) を使用します。StepOver を使う
    ときにすでに関数内にいる場合、それは効果がありません。関数呼び出しは表示
    されますが、実行はされません。

        DBG> v
        Windows PowerShell 2.0
        Have you run a background job today (Start-Job)?
        test.ps1:13 "Done $scriptName"

    StepOver コマンドは関数を実行し、スクリプト内の次のステートメント (最後の
    行を表示するもの) をプレビュー表示します。

    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
        Hit Command breakpoint on '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 (スクリプトの実行を許可しつつ
    最も制限の厳しいポリシー) に設定されている場合にのみ、コマンドブレーク
    ポイントが実行されます。

        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
        Hit Command breakpoint on '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=[]

    この例は、PowerShell デバッガーを使う多くの方法のうち、ほんの一部を示した
    ものです。

PowerShell のその他のデバッグ機能
    PowerShell には、PowerShell デバッガーに加えて、スクリプトや関数をデバッグ
    するために使用できる他のいくつかの機能が含まれています。

    - Set-PSDebug コマンドレットは、ステップ実行やトレースなど、非常に基本的な
      スクリプトデバッグ機能を提供します。

    - Set-StrictMode コマンドレットを使うと、初期化されていない変数への参照、
      オブジェクトの存在しないプロパティへの参照、有効でない関数構文を検出
      できます。

    - 変数の値を表示するステートメント、コマンドラインから入力を読み取る
      ステートメント、現在の命令を報告するステートメントなどの診断ステート
      メントをスクリプトに追加します。このタスクには、Write-Host、
      Write-Debug、Write-Warning、Write-Verbose など、Write 動詞を含む
      コマンドレットを使用します。

関連項目
    Disable-PSBreakpoint
    Enable-PSBreakpoint
    Get-PSBreakpoint
    Remove-PSBreakpoint
    Set-PSBreakpoint
    Get-PSCallStack
    Write-Debug
    Write-Verbose

----
原文: PowerShell-Docs (CC BY 4.0) の翻訳 / PSHelpJaJP