Unless you’re targeting PowerShell 1.0, there’s no need to set up your runspace and pipeline manually, create an instance of the PowerShell
class instead:
PowerShell psinstance = PowerShell.Create();
psinstance.AddScript(scriptPath);
var results = psinstance.Invoke();
Way simpler.
Now, the PowerShell
class exposes the various non-standard output streams (Verbose, Debug, Error etc.) – including the Progress Stream – via the Streams
property so you can subscribe to it, like so:
psinstance.Streams.Progress.DataAdded += myProgressEventHandler;
And then in your event handler:
static void myProgressEventHandler(object sender, DataAddedEventArgs e)
{
ProgressRecord newRecord = ((PSDataCollection<ProgressRecord>)sender)[e.Index];
if (newRecord.PercentComplete != -1)
{
Console.Clear();
Console.WriteLine("Progress updated: {0}", newRecord.PercentComplete);
}
}
As an example, here is that event handler shown above in action, while running a sample script that writes progress information (sample script posted below) in a simple console application:
Test-Progress.ps1
function Test-Progress
{
param()
Write-Progress -Activity 'Testing progress' -Status 'Starting' -PercentComplete 0
Start-Sleep -Milliseconds 600
1..10 |ForEach-Object{
Write-Progress -Activity "Testing progress" -Status 'Progressing' -PercentComplete $(5 + 6.87 * $_)
Start-Sleep -Milliseconds 400
}
Write-Progress -Activity 'Testing progress' -Status 'Ending' -PercentComplete 99
Start-Sleep -Seconds 2
Write-Progress -Activity 'Testing progress' -Status 'Done' -Completed
}
Test-Progress