Get-PSCallStack and Debugging

by Apr 11, 2019

In the previous tip we have used Get-PSCallStack to determine the “nest level” of code. Let’s today take a look at how this cmdlet can help during debugging. To illustrate this, save the below code to a script file. It is important that it is in fact is a ps1 file. Execute it in the PowerShell ISE.

function test1
{
    test2
}

function test2
{
Wait-Debugger
Get-Process 
    
}

test1

test1 is calling test2, and inside test2, there is a call to Wait-Debugger. This cmdlet was introduced in PowerShell 5 and breaks into the debugger. If you use an older version of PowerShell, you can set a breakpoint using F9. When you run the code, the debugger stops right before Get-Process is about to execute, and the line is highlighted in yellow (if not: did you save the code to file?).

In the interactive PowerShell console, you can now enter Get-PSCallStack to find out how you ended up in the script block where you are:

 
[DBG]: PS C:\>> Get-PSCallStack

Command Arguments Location        
------- --------- --------        
test2   {}        a1.ps1: Line 11
test1   {}        a1.ps1: Line 5 
a1.ps1  {}        a1.ps1: Line 14  
 

The output indicates that you are currently inside function test2 which was called by test1 which was called by a1.ps1.

You can get even more information when you look at the hidden InvocationInfo property:

 
[DBG]: PS C:\>> Get-PSCallStack | Select-Object -ExpandProperty InvocationInfo


MyCommand             : test2
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 5
OffsetInLine          : 5
HistoryId             : 17
ScriptName            : C:\Users\tobwe\Documents\PowerShell\a1.ps1
Line                  :     test2
                        
PositionMessage       : In C:\Users\tobwe\Documents\PowerShell\a1.ps1:5 Line:5
                        +     test2
                        +     ~~~~~
PSScriptRoot          : C:\Users\tobwe\Documents\PowerShell
PSCommandPath         : C:\Users\tobwe\Documents\PowerShell\a1.ps1
InvocationName        : test2
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition : 

MyCommand             : test1
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 14
OffsetInLine          : 1
HistoryId             : 17
ScriptName            : C:\Users\tobwe\Documents\PowerShell\a1.ps1
Line                  : test1
                        
PositionMessage       : In C:\Users\tobwe\Documents\PowerShell\a1.ps1:14 Line:1
                        + test1
                        + ~~~~~
PSScriptRoot          : C:\Users\tobwe\Documents\PowerShell
PSCommandPath         : C:\Users\tobwe\Documents\PowerShell\a1.ps1
InvocationName        : test1
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition : 

MyCommand             : a1.ps1
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 0
OffsetInLine          : 0
HistoryId             : 17
ScriptName            : 
Line                  : 
PositionMessage       : 
PSScriptRoot          : 
PSCommandPath         : 
InvocationName        : C:\Users\tobwe\Documents\PowerShell\a1.ps1
PipelineLength        : 2
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition : 
 

psconf.eu – PowerShell Conference EU 2019 – June 4-7, Hannover Germany – visit www.psconf.eu There aren’t too many trainings around for experienced PowerShell scripters where you really still learn something new. But there’s one place you don’t want to miss: PowerShell Conference EU – with 40 renown international speakers including PowerShell team members and MVPs, plus 350 professional and creative PowerShell scripters. Registration is open at www.psconf.eu, and the full 3-track 4-days agenda becomes available soon. Once a year it’s just a smart move to come together, update know-how, learn about security and mitigations, and bring home fresh ideas and authoritative guidance. We’d sure love to see and hear from you!

Twitter This Tip! ReTweet this Tip!