C# 获取Powershell命令';通过代码调用时的输出

C# 获取Powershell命令';通过代码调用时的输出,c#,powershell,azure,C#,Powershell,Azure,我已经编写了一段代码(用C#)来使用System.Management.Automation执行Powershell脚本(特别是Azure Powershell)。powershell脚本基本上在Azure上的容器中上载vhd,当通过Azure powershell手动输入命令时,该脚本会显示上载进度和经过的时间等。通过代码,一切正常,但我希望在命令执行期间(即pipeline.invoke();)获得命令的结果/输出(即上载进度、经过的时间),代码如下: RunspaceConfigurat

我已经编写了一段代码(用C#)来使用
System.Management.Automation
执行Powershell脚本(特别是Azure Powershell)。powershell脚本基本上在Azure上的容器中上载vhd,当通过Azure powershell手动输入命令时,该脚本会显示上载进度和经过的时间等。通过代码,一切正常,但我希望在命令执行期间(即
pipeline.invoke();
)获得命令的结果/输出(即上载进度、经过的时间),代码如下:

 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());
 }

如果可以从Powershell检索实时输出,请提供指导。

除非您的目标是Powershell 1.0,否则无需手动设置运行空间和管道,请创建以下的实例:

简单多了


现在,
PowerShell
类通过公开各种非标准输出流(详细、调试、错误等),包括进度流,以便您可以订阅,如下所示:

psinstance.Streams.Progress.DataAdded += myProgressEventHandler;
然后在事件处理程序中:

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);
    }
}

使用
PowerShell
类,而不是
管道
。然后异步调用并读取
PowerShell.Streams.Progress
您可以使用一些代码来指导更多内容吗?我添加了一个答案,感谢我尝试一下..说清楚一点,使用
DataAdded
eventhandler,您不需要异步调用它
Invoke()
将完成以下操作:嗨,我正在使用PowerShell类,但从未为我触发DataAdded事件。我的问题是为什么?我的代码如下所示:使用(PowerShell PowerShell=PowerShell.Create()){PowerShell.AddScript(scriptText);PowerShell.Streams.Progress.DataAdded+=ProgressDataAdded;Collection PSOutput=PowerShell.Invoke();}@IonuteCache,请包括处理程序代码和您迄今为止尝试的内容:)
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);
    }
}
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