Using Wait-Task function for capturing process.StandardOutput via ReadLineAsync()

Hi,

recently I’ve read a great post about async/await methods: Calling Async .NET Methods from PowerShell

Question: How to use Wait-Task function for capturing process.StandardOutput via ReadLineAsync()

So far I was able to capture only one line:

function Wait-Task {
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.Threading.Tasks.Task[]]$Task
    )

    Begin {
        $Tasks = @()
    }

    Process {
        $Tasks += $Task
    }

    End {
        While (-not [System.Threading.Tasks.Task]::WaitAll($Tasks, 200)) {}
        $Tasks.ForEach( { $_.GetAwaiter().GetResult() })
    }
}

Set-Alias -Name await -Value Wait-Task -Force

  $process = [System.Diagnostics.Process]::new()
  
  $process.StartInfo.RedirectStandardError = $true
  $process.StartInfo.RedirectStandardOutput = $true
  $process.StartInfo.UseShellExecute = $false
  $process.StartInfo.CreateNoWindow = $true
  #$process.StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
  $process.StartInfo.FileName = "ping"
  $process.StartInfo.WorkingDirectory = Split-Path (Split-Path $FilePath)
  $process.StartInfo.Arguments = [string]::Join(' ', @('127.0.0.0','-n','3'))
  $process.Start();
  $stdOut = Wait-Task -Task ($process.StandardOutput.ReadLineAsync())
  $stdOut  

I think that it’s just returning the first line, which is blank. Try using ReadToEndAsync.

function Wait-Task {
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.Threading.Tasks.Task[]]$Task
    )

    Begin {
        $Tasks = @()
    }

    Process {
        $Tasks += $Task
    }

    End {
        While (-not [System.Threading.Tasks.Task]::WaitAll($Tasks, 200)) {}
        $Tasks.ForEach( { $_.GetAwaiter().GetResult() })
    }
}

Set-Alias -Name await -Value Wait-Task -Force

  $process = [System.Diagnostics.Process]::new()
  
  $process.StartInfo.RedirectStandardError = $true
  $process.StartInfo.RedirectStandardOutput = $true
  $process.StartInfo.UseShellExecute = $false
  $process.StartInfo.CreateNoWindow = $true
  #$process.StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
  $process.StartInfo.FileName = "ping"
  $process.StartInfo.Arguments = [string]::Join(' ', @('127.0.0.0','-n','3'))
  $process.Start();
  $stdOut = Wait-Task -Task ($process.StandardOutput.ReadToEndAsync())
  $stdOut  

It’s helpful but I need to go line by line. I will try to combine it with one of the loops. Thanks!

1 Like