Cmdlets/src/XpandPosh.Cmdlets/Invoke-Parallel/Invoke-Parallel.cs
using System;
using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Reactive.Linq; using System.Reactive.Threading.Tasks; using System.Threading.Tasks; using XpandPosh.CmdLets; namespace XpandPosh.Cmdlets{ [Cmdlet(VerbsLifecycle.Invoke, "Parallel")] [CmdletBinding] public class InvokeParallel : XpandCmdlet{ private List<object> _values; private PSVariable[] _psVariables; [Parameter] public SwitchParameter IgnoreLastEditCode{ get; set; } [Parameter(Mandatory = true, Position = 3)] public ScriptBlock Script{ get; set; } [Parameter] public string[] VariablesToImport{ get; set; } = new string[0]; [Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true)] public object Value{ get; set; } protected override Task BeginProcessingAsync(){ _values = new List<object>(); _psVariables = this.Invoke<PSVariable>("Get-Variable") .Where(variable => VariablesToImport.Contains(variable.Name)).ToArray(); return base.BeginProcessingAsync(); } protected override Task ProcessRecordAsync(){ _values.Add(Value); return base.ProcessRecordAsync(); } protected override Task EndProcessingAsync(){ return _values.ToObservable() .SelectMany((o, i) => Observable.Start(() => { using (var runspace = RunspaceFactory.CreateRunspace()){ runspace.Open(); runspace.SetVariable(new PSVariable("_", o)); runspace.SetVariable(_psVariables); var psObjects = runspace.Invoke(Script.ToString()); if (!IgnoreLastEditCode){ var lastExitCode = runspace.Invoke("$LastExitCode").FirstOrDefault(); if (lastExitCode != null&& ((int) lastExitCode.BaseObject) >0){ var reason = string.Join(Environment.NewLine,runspace.Invoke("$Error")); throw new Exception($"ExitCode:{lastExitCode}{Environment.NewLine}Errors: {reason}{Environment.NewLine}Script:{Script}"); } } runspace.Close(); return psObjects; } }) .HandleErrors(this, ActivityName)) .WriteObject(this,_values.Count) .ToTask(); } } } |