3

Using a PowerShell script I will have to read and write to a console. We write an input and wait for an out that will be captured by $Reader.ReadLine(). But in some cases there wont be any output to get captured for the reader in that case the reader needs to look data from the stream and if there is no data the ReadLine() gets stuck/blocked waiting for the data from the console stream, whereas we need the ReadLine() to just wait for 5 seconds. If there is no data, it needs to get timed out and move on to the next command.

Please let me know whether there is any way to timeout $Reader.ReadLine() in PowerShell?

I see that in Java/C# we can use $Reader.ReadLine(1000) to timeout after 1 second but that doesn't seem to be working on PowerShell.

$tcpConnection = New-Object System.Net.Sockets.TcpClient($Computername, $Port)
$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true

$buffer = New-Object System.Byte[] 1024
$encoding = New-Object System.Text.AsciiEncoding 

while ($tcpStream.DataAvailable) {
    $reader.ReadLine()
}
if ($tcpConnection.Connected) {
    $writer.WriteLine($username)
    $reader.ReadLine()
    $writer.WriteLine($password)
    $reader.ReadLine()

    try {
        # if there is any data it will show here if there is no data then
        # it should get timed out after 5 seconds
        $Reader.ReadLine()
    } catch {
        Write-Host "Login Failed"
    }
}
7
  • i have not tested it, but this ... $Test = [System.IO.StreamReader]::Null; $Test.BaseStream.ReadTimeout seems to indicate that you can set the read timeout by assigning a value to that property. it appears to default to $Null. Commented Feb 27, 2019 at 9:32
  • @Lee_Dailey Thank you! but i get an error stating, Exception setting "ReadTimeout": "Timeouts are not supported on this stream. Commented Feb 27, 2019 at 10:33
  • i'm beyond my depth at this point. [blush] that info is all i can find. have you tried replacing the ::Null with ::New(<your_file_here>) - or whatever method is required to associate the reader with a target file? Commented Feb 27, 2019 at 10:52
  • @Lee_Dailey the target is not a file. But it's an output from a console (i.e., telnet session from command prompt) Commented Feb 27, 2019 at 11:24
  • then i can only say that if you can do it with c#, then the same method should work in powershell. if nothing else, you can simply embed the c# into powershell. Commented Feb 27, 2019 at 11:55

1 Answer 1

2

I would say that you should read this post C# Stream.Read with timeout

Converting that to your code sample, should end up with something like this.

$tcpConnection = New-Object System.Net.Sockets.TcpClient($Computername, $Port)

#This is one way you could try
$tcpConnection.ReceiveTimeout = 5000;

$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)

$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true

$buffer = New-Object System.Byte[] 1024
$encoding = New-Object System.Text.AsciiEncoding 

while ($tcpStream.DataAvailable) {
    $reader.ReadLine()
}
if ($tcpConnection.Connected) {
    $writer.WriteLine($username)
    $reader.ReadLine()
    $writer.WriteLine($password)
    $reader.ReadLine()

    try {
        # if there is any data it will show here if there is no data then
        # it should get timed out after 5 seconds
        $Reader.ReadLine()
    } catch {
        Write-Host "Login Failed"
    }
}

Take it for a spin and let me know if it works or not.

Updated: Updated to reflect the code to only contain the working solution.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.