Forum Discussion

helpdeskaleer's avatar
helpdeskaleer
Copper Contributor
Aug 25, 2022

How does one process / read from a pipe with no end in powershell?

So in Python, you can read from a pipe with no end from stdin.

It's great.

But is there a way to do this with Powershell?

1 Reply

  • LainRobertson's avatar
    LainRobertson
    Silver Contributor

    helpdeskaleer 

     

    You don't have to do anything special at all.

     

    Firstly, here's a working version of the URL from your post - for anyone else's benefit should they wish to add commentary:

     

     

    Secondly, the question from StackOverflow does actually feature an end - two, actually:

     

    1. A keyboard interruption;
    2. The source of the input ends naturally.

     

    Given the StackOverflow example uses ping, I'll do the same. Specifically, I'll use "ping -t" which generates output continually until interrupted by the "Ctrl + C" combination is pressed on the keyboard.

     

    While the example is not very useful, the key takeaway here is that nothing special needs to be done at all. The output from ping on the first line is simply sent to the script block and processed, and will keep doing so indefinitely until the user presses Ctrl + C to cancel ping or the ping commands ends for reasons of its own.

     

    i.e. you don't need to write some kind of dedicated handler to keep receiving input. Output is fed and processed as soon as it hits the pipeline, unlike the initial question put forward in StackOverflow where it was being delayed.

     

    Here's the example code:

    ping -t 8.8.8.8 |
        ForEach-Object {
            if ($_.StartsWith("Reply from") -or $_.StartsWith("General"))
            {
                if ($_ -match "bytes.*time.*ttl")
                {
                    $Status = "Link up";
                }
                else
                {
                    $Status = "Link down";
                }
    
                if (($null -eq $global:LinkState) -or ($global:LinkState -ne $Status))
                {
                    $global:LinkState = $Status;
                    
                    if ($Status -eq "Link up")
                    {
                        Write-Host -ForegroundColor Green -Object ("$([datetime]::Now.ToString("u")): $Status")
                    }
                    else
                    {
                        Write-Host -ForegroundColor Red -Object ("$([datetime]::Now.ToString("u")): $Status")
                    }
                }
            }
        }

     

    I created an outbound Windows Firewall rule to block ICMP from going out to 8.8.8.8 so I could trip the "failure" example, leading to this output - which would have continued indefinitely had I not terminated ping using "Ctrl + C".

     

     

    Cheers,

    Lain

Resources