Single Stepping a PowerShell Pipeline

As I was building up a moderately complicated pipeline in PowerShell, I was having some trouble and really wished there was a way to single step the pipeline so I could see the state of each item as it was processed. I wasn’t sure this was possible, but it is and I thought others might find it helpful. The magic is in the super powerful Set-PSBreakpoint cmdlet.

Because Set-PSBreakpoint can create breakpoints on not only lines and variable reads/writes, but also commands, I thought I’d try setting a breakpoint in the PowerShell console on one of the commands in the pipeline and it worked great! In the example below I will set a breakpoint on the Get-ChildItem cmdlet and when the breakpoint is hit, use the command line debugger to step through parts of the pipeline (the ‘s’ command is step into)

  1. PS C:Junk> Set-PSBreakpoint -Command Get-ChildItem
  3.   ID Script   Line Command        Variable    Action
  4.   -- ------   ---- -------        --------    ------
  5.    0               Get-ChildItem
  8. PS C:Junk> Get-ChildItem *.exe | ForEach-Object { $_.Name }
  9. Entering debug mode. Use h or ? for help.
  11. Hit Command breakpoint on 'Get-ChildItem'
  13. At line:1 char:1
  14. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  15. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. [DBG]: PS C:Junk>> s
  17. At line:1 char:38
  18. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  19. +                                      ~
  20. [DBG]: PS C:Junk>> s
  21. At line:1 char:40
  22. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  23. +                                        ~~~~~~~
  24. [DBG]: PS C:Junk>> s
  25. Foo.exe
  26. At line:1 char:48
  27. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  28. +                                                ~
  29. [DBG]: PS C:Junk>>

I love how the tildes show you exactly where you are in the pipeline. That makes it super easy to debug the pipeline. A little hint when single stepping pipelines is if you are setting a command breakpoint on something like Get-ChildItem, you’re going to hit it all the time. What I found works best is writing the commands in the ISE and pasting them into the console window where you want to debug.

For those of you that use the ISE most of the time, you have one problem. Here’s the same commands run in the ISE.

  1. PS C:Junk> Set-PSBreakpoint -Command Get-ChildItem
  3.   ID Script   Line Command        Variable    Action
  4.   -- ------   ---- -------        --------    ------
  5.    0               Get-ChildItem
  8. PS C:junk> Get-ChildItem *.exe | ForEach-Object { $_.Name }
  9. Hit Command breakpoint on 'Get-ChildItem'
  10. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  11. [DBG]: PS C:junk>> s
  13. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  14. [DBG]: PS C:junk>> s
  16. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  17. [DBG]: PS C:junk>>

For whatever reason, the ISE does not show the tildes where you are in the pipeline. Fortunately, it’s not hard to find where you are because the $PSDebugContext variable’s InvocationInfo field has all the information about everything going on at that point in the debugger.

  1. [DBG]: PS C:junk>> $PSDebugContext.InvocationInfo
  4. MyCommand             :
  5. BoundParameters       : {}
  6. UnboundArguments      : {}
  7. ScriptLineNumber      : 1
  8. OffsetInLine          : 40
  9. HistoryId             : 3
  10. ScriptName            :
  11. Line                  : Get-ChildItem *.exe | ForEach-Object { $_.Name }
  12. PositionMessage       : At line:1 char:40
  13.                         + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  14.                         +                                        ~~~~~~~
  15. PSScriptRoot          :
  16. PSCommandPath         :
  17. InvocationName        :
  18. PipelineLength        : 0
  19. PipelinePosition      : 0
  20. ExpectingInput        : False
  21. CommandOrigin         : Internal
  22. DisplayScriptPosition :

As you can see, the PositionMessage is the important data. In my ISE profile, I added the following function to make it easy to see where I’m at when single stepping a pipeline.

  1. function cpo
  2. {
  3.     if (test-path variable:/PSDebugContext)
  4.     {
  5.         $PSDebugContext.InvocationInfo.PositionMessage
  6.     }
  7. }

Single stepping the pipeline isn’t super ninja magic like some of those PowerShell people do but this sure helped me figure out what was going on in my troublesome pipeline.

WintellectNOW is New And Improved

We’ve recently completed a significant user experience upgrade on our WintellectNOW online training site.  Here’s an overview of what’s new! The fantastic library of video training from the software industry’s best and brightest just got easier to use with the latest upgrade to the WintellectNOW site.  This upgrade centers around making our technical content easier to discover and…

.NET Open Source Explained

In a recently posted video on Channel 9, Microsoft’s Immo Landwerth and David Kean explain the reasoning behind making .NET Open Source. In this video, Dan Hernandez talks to Immo Landwerth and David Kean from the .NET Framework team to explain the thinking that went into the decision to open source the .NET Framework as…

New Report Sites Significant Security Vulnerabilities in Android Devices

Security firm TrendMicro has released a new report that states that 75% of users are vulnerable to multiple attacks. In their latest Quarterly Security Roundup, TrendLabs calls out several key vulnerabilities in recent Android OS including the FakeID issue and Android Browser flaws.  The FakeID vulnerability was originally discovered earlier this year by BlueBox Labs and…

Seize the Opportunity of the Internet of Things

There are a lot of newcomers to the Internet of Things (IoT) and Machine to Machine (M2M) space lately. Many of them love to speak authoritatively and often use vending machines as their favorite example use case to illustrate the value of IoT. When you see me use vending machines in a similar fashion, it’s…

My Introduction To Data Science With F#

You may have seen a big boom lately with web technologies, especially with all of the JavaScript frameworks coming out at a pace of around one a week. But there is another boom you may have heard about…data science. Now I’ll be the first t...

Has Google Become Too Big?

The European Parliament has passed a new resolution calling for regulations on Internet search providers even recommending that search be separated from other online services. It seems that Google now finds itself in the crosshairs of the European Union in much the same way that Microsoft did in 2004.  While still dealing with privacy issues…

Microsoft Updates its “By The Numbers” Interactive Visuals

Microsoft has released its latest “By The Numbers” interactive visuals with some interesting new statistics Microsoft’s latest version of their “By The Numbers” Metro-style visual campaign shows some significant Azure adoption numbers as well as strong usage of their other online services such as Skype, OneDrive, and XBox Live.  Here are a few of the more…

Windows Phone 8.1 Developer Roadmap

In a recent blog post, Microsoft’s Mohamed Yamama has released an updated infographic showing resources for learning, porting, designing, building, testing, publishing, and monetizing your Windows Phone 8.1 Apps.

Wanna Build a Snowman? Let Anna and Elsa Teach Your Kids to Code

Disney and have teamed up to create a special “Hour of Code” tutorial based on Disney’s hit movie “Frozen”! Your kids can learn the basics or programming like loops, branches, and functions in this interactive tutorial while helping Frozen’s Elsa and Anna build beautiful snowflakes.  The tutorial uses visual representations of code structures and…

5 Questions with Naomi Moneypenny

At the recent DevIntersection conference we got a chance to sit down with speaker Naomi Moneypenny to discuss machine learning and how it can be used to create better connections.   Naomi Moneypenny is CTO at Synxi (a ManyWorlds brand) where she leads the development team for the adaptive recommendations & learning engine for SharePoint…