다음을 통해 공유


about_Debuggers

간단한 설명

PowerShell 디버거에 대해 설명합니다.

자세한 설명

디버깅은 스크립트 명령에서 오류를 식별하고 수정하기 위해 실행되는 동안 스크립트를 검사하는 프로세스입니다. PowerShell 디버거를 사용하면 스크립트, 함수, 명령, PowerShell DSC(필요한 상태 구성) 구성 또는 식에서 오류 및 비효율성을 검사하고 식별할 수 있습니다.

PowerShell 5.0부터 PowerShell 디버거는 원격 컴퓨터의 콘솔 또는 Windows PowerShell ISE(통합 스크립팅 환경)에서 실행되는 스크립트, 함수, 명령, 구성 또는 식을 디버그하도록 업데이트되었습니다.

참고 항목

Windows PowerShell ISE는 Windows PowerShell만 지원합니다. PowerShell 6 이상의 경우 PowerShell 확장과 함께 Visual Studio Code를 사용해야 합니다. 자세한 내용은 Visual Studio Code를 사용한 디버깅을 참조하세요.

디버거 cmdlet

PowerShell 디버거에는 다음 cmdlet 집합이 포함됩니다.

  • Set-PSBreakpoint: 줄, 변수 및 명령에 중단점을 설정합니다.
  • Get-PSBreakpoint: 현재 세션의 중단점을 가져옵니다.
  • Disable-PSBreakpoint: 현재 세션에서 중단점을 해제합니다.
  • Enable-PSBreakpoint: 현재 세션에서 중단점을 다시 사용하도록 설정합니다.
  • Remove-PSBreakpoint: 현재 세션에서 중단점을 삭제합니다.
  • Get-PSCallStack: 현재 호출 스택을 표시합니다.

디버거 시작 및 중지

디버거를 시작하려면 하나 이상의 중단점을 설정한 다음 디버그하려는 스크립트, 명령 또는 함수를 실행합니다.

중단점에 도달하면 실행이 중지되고 컨트롤이 디버거로 인계됩니다.

디버거를 중지하려면 스크립트, 명령 또는 함수가 완료될 때까지 실행합니다. 또는 형식 stop 또는 t.

디버거 명령

PowerShell 콘솔에서 디버거를 사용하는 경우 다음 명령을 사용하여 실행을 제어합니다. Windows PowerShell ISE에서 디버그 메뉴의 명령을 사용합니다.

참고 항목

다른 호스트 애플리케이션에서 디버거를 사용하는 방법에 대한 자세한 내용은 호스트 애플리케이션 설명서를 참조하세요.

  • s, StepInto: 다음 문을 실행한 다음 중지합니다.

  • v, StepOver: 다음 문을 실행하지만 함수 및 호출을 건너뜁니다. 건너뛴 문은 실행되지만 단계별 실행은 아닙니다.

  • Ctrl+Break: (ISE에서 모두 중단) PowerShell 콘솔 또는 Windows PowerShell ISE 내에서 실행 중인 스크립트로 나뉩니다. Windows PowerShell 2.0, 3.0 및 4.0의 Ctrl+Break는 프로그램을 닫습니다. Break All은 로컬 및 원격 대화형으로 실행되는 스크립트 모두에서 작동합니다.

  • o, StepOut: 현재 함수에서 한 단계씩 나가고 중첩된 경우 한 수준 위로 올라갔습니다. 본문에 있는 경우 끝 또는 다음 중단점까지 계속됩니다. 건너뛴 문은 실행되지만 단계별 실행은 아닙니다.

  • c, Continue: 스크립트가 완료되거나 다음 중단점에 도달할 때까지 계속 실행됩니다. 건너뛴 문은 실행되지만 단계별 실행은 아닙니다.

  • l, List: 실행 중인 스크립트의 부분을 표시합니다. 기본적으로 현재 줄, 5개의 이전 줄 및 10개의 후속 줄이 표시됩니다. 스크립트를 계속 나열하려면 Enter 키를 누릅니다.

  • l <m>, List: 로 지정된 줄 번호로 시작하는 스크립트의 16줄을 <m>표시합니다.

  • l <m> <n>, List: 로 지정된 <m>줄 번호부터 시작하여 스크립트의 줄을 표시 <n> 합니다.

  • q, StopExit: 스크립트 실행을 중지하고 디버거를 종료합니다. cmdlet Exit 을 실행 Debug-Job 하여 작업을 디버깅하는 경우 명령은 디버거를 분리하고 작업이 계속 실행되도록 허용합니다.

  • k, Get-PsCallStack: 현재 호출 스택을 표시합니다.

  • <Enter>: (), () StepOver 또는 List (svl)인 경우 Step 마지막 명령을 반복합니다. 그렇지 않으면 제출 작업을 나타냅니다.

  • ?, h: 디버거 명령 도움말을 표시합니다.

디버거를 종료하려면 (q)를 사용할 Stop 수 있습니다.

PowerShell 5.0부터 Exit 명령을 실행하여 시작하거나 Debug-Runspace실행 Debug-Job 하여 시작한 중첩된 디버깅 세션을 종료할 수 있습니다.

이러한 디버거 명령을 사용하여 스크립트를 실행하고, 우려 지점에서 중지하고, 변수 값과 시스템 상태를 검사하고, 문제를 식별할 때까지 스크립트를 계속 실행할 수 있습니다.

참고 항목

리디렉션 연산 >자를 사용하여 문을 한 단계씩 실행하면 PowerShell 디버거가 스크립트의 나머지 모든 문을 단계별로 실행합니다.

스크립트 변수의 값 표시

디버거에 있는 동안 명령을 입력하고, 변수 값을 표시하고, cmdlet을 사용하고, 명령줄에서 스크립트를 실행할 수도 있습니다. 다음 자동 변수를 제외하고 디버그 중인 스크립트에 있는 모든 변수의 현재 값을 표시할 수 있습니다.

$_
$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)

디버깅 및 범위

디버거에 침입해도 작업 중인 범위는 변경되지 않지만 스크립트의 중단점에 도달하면 스크립트 범위로 이동합니다. 스크립트 범위는 디버거를 실행한 범위의 자식입니다.

스크립트 범위에 정의된 변수 및 별칭을 찾으려면 or Get-Variable cmdlet의 Scope 매개 변수를 Get-Alias 사용합니다.

예를 들어 다음 명령은 로컬(스크립트) 범위의 변수를 가져옵니다.

Get-Variable -scope 0

이는 스크립트에서 정의한 변수와 디버깅하는 동안 정의한 변수만 볼 수 있는 유용한 방법입니다.

명령줄에서 디버깅

변수 중단점 또는 명령 중단점을 설정하는 경우 스크립트 파일에서만 중단점을 설정할 수 있습니다. 그러나 기본적으로 중단점은 현재 세션에서 실행되는 모든 항목에 대해 설정됩니다.

예를 들어 변수에 $name 중단점을 설정하는 경우 디버거는 중단점을 사용하지 않도록 설정하거나 제거할 때까지 실행하는 스크립트, 명령, 함수, 스크립트 cmdlet 또는 식의 모든 $name 변수에서 중단됩니다.

이렇게 하면 세션 및 사용자 프로필의 함수, 변수 및 기타 스크립트의 영향을 받을 수 있는 보다 현실적인 컨텍스트에서 스크립트를 디버그할 수 있습니다.

줄 중단점은 스크립트 파일과 관련이 있으므로 스크립트 파일에서만 설정됩니다.

디버깅 함수

및 섹션이 있는 beginprocessend 함수에 중단점을 설정하면 디버거가 각 섹션의 첫 번째 줄에서 중단됩니다.

예시:

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에서 설정되었습니다. 디버거가 시작되면 프롬프트에 두 가지 식별 변경 내용이 있습니다.

  • 세션이 실행 중인 컴퓨터의 이름입니다.
  • 디버깅 모드에 있음을 알려주는 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 스크립트의 첫 번째 줄에 줄 중단점을 만듭니다.

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 명령을 사용하여 스크립트에서 첫 번째 문을 실행하고 다음 문을 미리 봅니다. 다음 문은 자동 변수를 사용하여 $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

다른 단계 명령을 사용하여 함수 호출을 실행합니다. Enter 키를 누르거나 단계에 "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 명령은 마지막 명령을 실행합니다. 표준 명령 프롬프트는 디버거가 종료되고 명령 프로세서에 컨트롤을 반환했음을 나타냅니다.

이제 디버거를 다시 실행합니다. 먼저 현재 중단점을 삭제하려면 및 Remove-PsBreakpoint cmdlet을 Get-PsBreakpoint 사용합니다. 중단점을 다시 사용할 수 있다고 생각되면 .대신 Remove-PsBreakpointcmdlet을 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>

변수의 현재 값(예$null: .)을 $scriptName 표시합니다.

DBG> $scriptName
DBG>

명령(s)을 Step 사용하여 변수를 채우는 문을 실행합니다. 그런 다음 변수의 새 값을 표시합니다 $scriptName .

DBG> $scriptName
C:\ps-test\test.ps1

단계 명령을 사용하여 스크립트에서 다음 문을 미리 봅니다.

DBG> s
test.ps1:12  psversion

다음 문은 함수에 대한 호출입니다 psversion . 함수를 건너뛰지만 계속 실행하려면 명령(v)을 StepOver 사용합니다. 사용할 StepOver때 함수에 이미 있는 경우 유효하지 않습니다. 함수 호출이 표시되지만 실행되지 않습니다.

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

StepOver 명령은 함수를 실행하고 스크립트에서 마지막 줄을 출력하는 다음 문을 미리 봅니다.

명령(t)을 Stop 사용하여 디버거를 종료합니다. 명령 프롬프트가 표준 명령 프롬프트로 돌아갑니다.

C:\ps-test>

중단점을 삭제하려면 해당 및 Remove-PsBreakpoint cmdlet을 사용합니다Get-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>

스크립트는 함수 호출 시 중단점에 도달합니다. 이 시점에서 함수는 아직 호출되지 않았습니다. 이렇게 하면 Action 매개 변수 Set-PSBreakpoint 를 사용하여 중단점 실행에 대한 조건을 설정하거나 로그 시작 또는 진단 또는 보안 스크립트 호출과 같은 준비 또는 진단 작업을 수행할 수 있습니다.

작업을 설정하려면 계속 명령(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 cmdlet 또는 디버거 명령(k)을 Get-PsCallStack 사용합니다. 다음 명령은 현재 호출 스택을 가져옵니다.

DBG> k
2: prompt
1: .\test.ps1: $args=[]
0: prompt: $args=[]

이 예제에서는 PowerShell 디버거를 사용하는 몇 가지 방법만 보여 줍니다.

PowerShell의 기타 디버깅 기능

PowerShell 디버거 외에도 PowerShell에는 스크립트 및 함수를 디버그하는 데 사용할 수 있는 몇 가지 다른 기능이 포함되어 있습니다.

  • cmdlet은 Set-PSDebug 단계별 실행 및 추적을 비롯한 매우 기본적인 스크립트 디버깅 기능을 제공합니다.

  • Set-StrictMode cmdlet을 사용하여 초기화되지 않은 변수에 대한 참조를 검색하고, 개체의 존재하지 않는 속성에 대한 참조를 검색하고, 유효하지 않은 구문을 함수합니다.

  • 변수 값을 표시하는 문, 명령줄에서 입력을 읽는 문 또는 현재 명령을 보고하는 문과 같은 진단 문을 스크립트에 추가합니다. 이 작업에 대한 쓰기 동사가 포함된 cmdlet(예: Write-Host, Write-Debug, Write-WarningWrite-Verbose.)을 사용합니다.

참고 항목