通过代码调用时获取Powershell命令的输出

通过代码调用时获取Powershell命令的输出

本文介绍了通过代码调用时获取Powershell命令的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用C#编写了一段代码,以使用System.Management.Automation执行Powershell脚本(特别是Azure PowerShell). Powershell脚本基本上将vhd上载到Azure上的容器中,当通过azure Powershell手动输入命令时,它会显示上载进度和经过的时间等.通过代码,一切正常,但我想获取命令的结果/输出(即上传进度,经过的时间),在命令执行期间(即pipeline.invoke();),这里是代码:

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

请指导是否可以从Powershell检索实时输出.

Please guide if it is possible to retrieve live output from Powershell.

推荐答案

除非您的目标是PowerShell 1.0,否则无需手动设置运行空间和管道,只需创建 PowerShell代替:

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

更简单.

现在,PowerShell类通过 Streams属性,因此您可以订阅它,就像这样:

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:

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

这篇关于通过代码调用时获取Powershell命令的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 04:00