I am using a PowerShell script to execute a console application and I am trying to redirect the standard output and the standard error from there. The code I am using is the following:
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "myExe.exe"
$ProcessInfo.Arguments = "bla bla bla"
$ProcessInfo.RedirectStandardError = $true
$ProcessInfo.RedirectStandardOutput = $true
$ProcessInfo.UseShellExecute = $false
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
$output = $Process.StandardOutput.ReadToEnd()
$errors = $Process.StandardError.ReadToEnd()
$Process.WaitForExit()
$output
$errors
return $Process.ExitCode
So far so good, if I have an error I can see it redirected into my PowerShell console and if I have output it is also redirected. The issue is that this process takes 10 minutes and in the meantime we have no clue of what is going on.
Is there any way in PowerShell I can stream the content of the Output and the Error while the process is running? In pure .NET we can subscribe to events of the Process class, can I do the same in PowerShell?
Is there any way in PowerShell I can stream the content of the Output and the Error while the process is running? In pure .NET we can subscribe to events of the Process class, can I do the same in PowerShell?
Sure you can! What you need is an Object Events:
An object event is a .Net object that not only has the usual Properties and Methods in the object, but also has another member called Event, which you can register a subscription on using Register-ObjectEvent
Here is slightly modified example from the the PowerShell forums. It will output data from the ping command asynchronously (at least from the script point of view):
# Setup stdin\stdout redirection
$StartInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = 'ping.exe'
Arguments = '-t 127.0.0.1'
UseShellExecute = $false
RedirectStandardOutput = $true
RedirectStandardError = $true
}
# Create new process
$Process = New-Object System.Diagnostics.Process
# Assign previously created StartInfo properties
$Process.StartInfo = $StartInfo
# Register Object Events for stdin\stdout reading
$OutEvent = Register-ObjectEvent -Action {
Write-Host $Event.SourceEventArgs.Data
} -InputObject $Process -EventName OutputDataReceived
$ErrEvent = Register-ObjectEvent -Action {
Write-Host $Event.SourceEventArgs.Data
} -InputObject $Process -EventName ErrorDataReceived
# Start process
[void]$Process.Start()
# Begin reading stdin\stdout
$Process.BeginOutputReadLine()
$Process.BeginErrorReadLine()
# Do something else while events are firing
do
{
Write-Host 'Still alive!' -ForegroundColor Green
Start-Sleep -Seconds 1
}
while (!$Process.HasExited)
# Unregister events
$OutEvent.Name, $ErrEvent.Name |
ForEach-Object {Unregister-Event -SourceIdentifier $_}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With