I am implementing a WPF application that executes a PowerShell script for each key/value pair given in a dictionary, using the pair as script arguments. I store each run of the script as a new command in the pipeline. However, this causes me to only get output back from the last command that was run, when I need the output after each run of the script. I have considered creating a new pipeline each time the script is executed, but I need to know when all executions of the script are done. Here's the relevant code to help explain my problem:
private void executePowerShellScript(String scriptText, Dictionary<String, String> args)
{
// Create the PowerShell object.
PowerShell powerShell = PowerShell.Create();
// If arguments were given, add the script and its arguments.
if (args != null)
{
foreach (KeyValuePair<String, String> arg in args)
{
powerShell.AddScript(scriptText);
powerShell.AddArgument(arg.Key);
powerShell.AddArgument(arg.Value);
}
}
// Otherwise, just add the script.
else
powerShell.AddScript(scriptText);
// Add the event handlers.
PSDataCollection<PSObject> output = new PSDataCollection<PSObject>();
output.DataAdded += new EventHandler<DataAddedEventArgs>(Output_DataAdded);
powerShell.InvocationStateChanged +=
new EventHandler<PSInvocationStateChangedEventArgs>(Powershell_InvocationStateChanged);
// Invoke the pipeline asynchronously.
IAsyncResult asyncResult = powerShell.BeginInvoke<PSObject, PSObject>(null, output);
}
private void Output_DataAdded(object sender, DataAddedEventArgs e)
{
PSDataCollection<PSObject> myp = (PSDataCollection<PSObject>)sender;
Collection<PSObject> results = myp.ReadAll();
foreach (PSObject result in results)
{
Console.WriteLine(result.ToString());
}
}
And then I use the following method to know when all executions of the script have been completed. Since I do this by checking that the invocation state of the pipeline is completed, I can't make a new pipeline for each execution of the script:
private void Powershell_InvocationStateChanged(object sender, PSInvocationStateChangedEventArgs e)
{
switch (e.InvocationStateInfo.State)
{
case PSInvocationState.Completed:
ActiveCommand.OnCommandSucceeded(new EventArgs());
break;
case PSInvocationState.Failed:
OnErrorOccurred(new ErrorEventArgs((sender as PowerShell).Streams.Error.ReadAll()));
break;
}
Console.WriteLine("PowerShell object state changed: state: {0}\n", e.InvocationStateInfo.State);
}
So, to get to my question:
1) Can I force the pipeline to produce output after each command that it executes? Or,
2) If I were to create a new pipeline each time I run the command, is there another way that I could check that all executions of the script have been completed?
There are few examples using the actual PowerShell class in C# and I know next to nothing about threading, so any help would be greatly appreciated.