Powershell: Allow user code to stop a pipeline on demand / to terminate upstream cmdlets.

Created on 19 May 2017  路  6Comments  路  Source: PowerShell/PowerShell

The ability to stop a pipeline on demand is currently only available _internally_, as used by Select-Object -First <n>, for instance.

To quote from this uservoice.com issue:

It is of great value to be able to stop the pipeline if your mission is completed before the emitting cmdlet has provided all results.

In fact, the PS pipeline would gain a completely new "feature". Currently, it is a memory throttle and provides realtime feedback at the cost of performance. If stopping the pipeline was something available to users, it could also be a generic means of running cmdlets only partially.

Select-Object is a great start but you do not always know beforehand how many elements you need. So it would be beneficial to have a Stop-Pipeline cmdlet or at least a public StopUpstreamCommandsException that a script programme can throw.

A real-world example.

Also note that there are two distinct ways to "stop" a pipeline:

  • Exiting the entire pipeline _instantly_ (effectively aborting it) - with downstream cmdlets _not_ getting a chance to run their End blocks, as simulated by this command using break with a dummy loop to break out of:
# Produces NO output, because Sort-Object's End block never runs.
do { 
  1..10 | % { if ($_ -gt 2) { break }; $_ } | Sort-Object -Descending
 } while ($False)

Note that _without_ the final Sort-Object -Descending pipeline stage, you _would_ see output, because the objects are being output in the % script block as they're being received.

This quiet termination of the entire pipeline is similar to a statement-terminating error that is silenced.


  • Stopping only the _upstream_ cmdlets (the cmdlet calls in _earlier_ pipeline stages), as Select-Object -First <n> does, for instance, giving _downstream_ cmdlets a chance to run their End blocks.
# Produces (2, 1), because Sort-Object's End block IS run.
1..10 | Select-Object -First 2 | Sort-Object -Descending

This scenario is about _stopping further input_, while still allowing remaining pipeline stages to finish their processing.

However, the fact that the upstream cmdlets do _not_ also get to run their End blocks can be problematic, as that may be required for cleanup tasks: see https://github.com/PowerShell/PowerShell/issues/7930; PR #9900 would instead introduce a cleanup block to ensure cleanup even when stopped via StopUpstreamCommandsException.


Originally reported for:

PowerShell Core v6.0.0-beta (v6.0.0-beta.1)
Issue-Discussion Issue-Enhancement WG-Engine

Most helpful comment

Things that don't necessarily align with the PowerShell Team's priorities (which is not static) can still get done if contributed by the community :)

All 6 comments

There is a good detailed blog post on how to implement this in PowerShell today: Cancelling a Pipeline. I think it would be useful to implement something like as a built-in cmdlet.

Thanks, @dragonwolf83; the blog post's author, Tobias Weltner, is the same person who created the linked uservoice.com issue; the blog post elicited the following @jpsnover response (dated "over 7 years ago"):

We have wanted to add pipeline stopping for quite a while and it never got raised above the bar.

That's one lofty bar! :)

Things that don't necessarily align with the PowerShell Team's priorities (which is not static) can still get done if contributed by the community :)

We need RFC for new cmdlet and examples of how to use the cmdlet.

Does anyone have a working link to Tobias' blog post mentioned above? That link seems to be dead.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SteveL-MSFT picture SteveL-MSFT  路  3Comments

rkeithhill picture rkeithhill  路  3Comments

aragula12 picture aragula12  路  3Comments

HumanEquivalentUnit picture HumanEquivalentUnit  路  3Comments

manofspirit picture manofspirit  路  3Comments