Get Powershell command’s output when invoked through code

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:

readProgress

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

Leave a Comment