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:
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
Muhammad Murad Haider
Updated on December 22, 2020Comments
-
Muhammad Murad Haider over 3 years
I have written a piece of code (in C#) to execute a Powershell script (specifically Azure PowerShell) using
System.Management.Automation
. The powershell script basically uploads a vhd in a container on Azure, which shows the upload progress and time elapsed etc when command is manually entered through azure Powershell. Through code everything works fine but i want to get the result/output of a command (i.e. upload progress, time elapsed), during command execution (i.e.pipeline.invoke();
) here is the code:RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); Pipeline pipeline = runspace.CreatePipeline(); Command myCommand = new Command(scriptPath); foreach (var argument in arguments) { myCommand.Parameters.Add(new CommandParameter(argument.Key, argument.Value)); } pipeline.Commands.Add(myCommand); var results = pipeline.Invoke(); // i want to get results here (i.e. during command execution) foreach (var psObject in results) { System.Diagnostics.Debug.Write(psObject.BaseObject.ToString()); }
Please guide if it is possible to retrieve live output from Powershell.
-
Ionut Enache over 5 yearsHi, I am using the PowerShell class but the DataAdded event is never triggered for me. My question is why? My code looks like this: using (PowerShell powerShell = PowerShell.Create()) { powerShell.AddScript(scriptText); powerShell.Streams.Progress.DataAdded += ProgressDataAdded; Collection<PSObject> PSOutput = powerShell.Invoke(); }
-
Mathias R. Jessen over 5 years@IonutEnache Please ask a new question and include the handler code and what you've tried so far :)