问题描述
我编写了一段代码(用 C#)来使用 System.Management.Automation
执行 Powershell 脚本(特别是 Azure PowerShell).powershell 脚本基本上是在 Azure 上的容器中上传 vhd,当通过 azure Powershell 手动输入命令时,它会显示上传进度和经过的时间等.通过代码一切正常,但我想在命令执行期间(即 pipeline.invoke();
)获取命令的结果/输出(即上传进度、已用时间),这里是代码:
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();运行空间运行空间 = RunspaceFactory.CreateRunspace(runspaceConfiguration);运行空间.打开();RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);管道管道 = runspace.CreatePipeline();命令 myCommand = 新命令(脚本路径);foreach(参数中的 var 参数){myCommand.Parameters.Add(new CommandParameter(argument.Key,argument.Value));}管道.命令.添加(我的命令);var 结果 = pipeline.Invoke();//我想在这里得到结果(即在命令执行期间)foreach(结果中的var psObject){System.Diagnostics.Debug.Write(psObject.BaseObject.ToString());}
请指导是否可以从 Powershell 检索实时输出.
除非您的目标是 PowerShell 1.0,否则无需手动设置运行空间和管道,只需创建
测试进度.ps1
function Test-Progress{参数()写入进度-活动测试进度"-状态开始"-PercentComplete 0Start-Sleep -Milliseconds 6001..10 |ForEach-Object{写入进度-活动测试进度"-状态进度"-PercentComplete $(5 + 6.87 * $_)Start-Sleep -Milliseconds 400}写入进度-活动测试进度"-状态结束"-PercentComplete 99开始-睡眠-秒 2写入进度-活动测试进度"-状态完成"-已完成}测试进度
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.
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
这篇关于通过代码调用时获取 Powershell 命令的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!