Interactive Pipelines

This post shows you how to work interactively with a running pipeline in PowerShell

Overview

The PowerShell pipeline is awesome. It makes it a breeze to chain together various commands that you want to perform on an object. Sometimes when you create a quick chain of commands on the PowerShell terminal, you want to have some better visibility on what is actually happening behind the scenes:

  1. How many iterations have already happened?
  2. How long until the command is all done?
  3. How does an object gets transformed between cmdlets?
  4. What is the current object? As JSON?

This post will introduce my latest module, PoshInteractive, to accomplish these tasks.

Installing PoshInteractive

You can install the module by opening up a PowerShell window and pasting in this command:

Install-Module PoshInteractive -Scope CurrentUser

PoshInteractive

PoshInteractive was inspired by SeeminglyScience’s Github gist that demonstrates how to stop the steppable pipeline like how Select-Object -First 2 doesn’t raise any errors when it prematurely closes the pipeline. From there, I figured that a pipeline inspector that can do more than close the current pipe could be a fun thing to have around. And now, it can do all of these things:

  1. Show a quick command reference
  2. Close the pipeline
  3. Pause the pipeline
  4. Display Write-Progress status on demand
  5. Toggle showing the Write-Progress status as objects flow through the pipeline
  6. Iterate through objects in the pipeline one at a time
  7. Inspect pipeline data as it passes from one step to another
  8. Display current item in the pipeline
  9. Display current item in the pipeline as JSON data
  10. Enter a nested prompt

Don’t worry, ample examples coming at you now!

Command Reference

While processing items in the pipeline, hit ? to see a list of the commands that you can run. It will also wait for you to pick a command before continuing.

Help

Closing the pipeline

Hit Q during processing will make it exit before sending the next object down the pipeline.

$null = Invoke-InteractivePipeline  (1..1000000) -ShowProgress

Shown here

Pausing the pipeline

Press P to pause the pipeline. Press any key that isn’t a command key to resume processing.

When the pipeline is paused, running commands doesn’t automatically unpause the pipeline. When the pipeline isn’t paused, pressing command keys to do something will not pause the pipeline for more commands.

Displaying Write-Progress on Demand

To do a 1-time display of the current item via Write-Progress, hit your spacebar. To do it again, hit spacebar again. Pretty easy.

Toggling Write-Progress Status

To make the Write-Progress status continually update, press s.

Shown here

Iterating Through the Pipeline

This command is most effective when you are in command mode and want to manually move on to next item. Press n to advance! Or the down arrow key. Great to combine it with i or j to look at your data.

Inspecting Data that Passes Through the Pipeline

Another command that is especially useful for command mode is the c to inspect the current object as a string. Press j to view it as JSON string.

Additionally, you can follow pipeline data as it traverses through several cmdlets by using the right and left arrows (and ,/. keys). This makes it easy to see how your pipeline data is getting transformed in the pipeline.

Consider what happens to each number as it passes through this chain. Can you look at this shorthand command and follow what’s going to happen to each number?

0..100 | %{$_/2} | measure -Average

If you can’t, no need to worry! Add a couple interactives in and watch it yourself. Run this command and hit n a few times to advance a few objects. From there, inspect the current item with c, then press <right> or . to move to the Interactive to the right. Press c again to see its current state.

0..100 | Interactive -Pause | %{$_/2} | Interactive | measure -Average

Shown here

You can press <left> or , to move your command inspection back up the pipeline to the 1st invocation of Interactive, but the current object will get dumped out of the pipe and it’ll pause with the next pipeline input instead.

Entering Nested Prompt

The nested prompt is a handy tool for interactive debugging in a pipeline - when you need full power. To use it, just hit e to enter, and then type exit to resume pipeline processing after.

Wrapping up

Remember, the Invoke-InteractivePipeline has two aliases: Interactive and iip. I hope this tool can help you for some of your one-off scripting needs :)

Discussion

Discuss on reddit