PowerShell LINQ: Skip-While

Next up in the PowerShell LINQ series is SkipWhile.  This LINQ function takes an enumerable instance and a predicate.  The function will skip the elements in the enumerable while the predicate is true.  The argument to the predicate is the current value of the enumerable. 

The LINQ version takes a predicate in the form of a Func<T,TResult>.  The PowerShell equivalent of a delegate is a script block.  Unlike a .Net delegate, there is no way to type the Skip-While function to accept a particular number or type of arguments.  The contract with the caller will be implicit.

Other than the strict typing, the function will match the contract for the LINQ version of SkipWhile.

# Skip while the condition is true
function Skip-While() {
    param ( [scriptblock]$pred = $(throw "Need a predicate") )
    begin {
        $skip = $true
    process {
        if ( $skip ) {
            $skip = & $pred $_

        if ( -not $skip ) {
    end {}

Example Usage:

PS) 1..10 | Skip-While { $args[0] -lt 6 }
Comments (2)

  1. Here’s a trick to get your lambdas to use the standard $_ convention for current item.

    This used to work and I think it still does if the function is a "normal" .ps1 style function:

    function Blah([ScriptBlock]$Predicate) {

      process { if (&$Predicate) { $_ } }


    1,2,3 | blah { $_ -eq 3 }

    But that no longer works in PowerShell 2.0 CTP 3 when using a .psm1. I still can’t quite figure out why but I think it has something to do with the way PowerShell is capturing the variable before calling the function.

    So anyway, this does in fact work:

    function Blah([ScriptBlock]$Predicate) {

      process { if (Invoke-Expression "$Predicate") { $_ } }


    Notice how the Predicate is being converted back to a string and passed to iex which inherits the $_ variable.

    Anyhow, I got sick of using $args[0] for my predicates when everywhere else used $_ so I banged my head against the wall for hours until I figured out a suitable workaround.