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-Objectis a great start but you do not always know beforehand how many elements you need. So it would be beneficial to have aStop-Pipelinecmdlet or at least a publicStopUpstreamCommandsExceptionthat a script programme can throw.
Also note that there are two distinct ways to "stop" a pipeline:
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.
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)
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.
Here鈥榮 some material: http://www.powertheshell.com/stop_pipeline/
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 :)