public async Task <Result> ExecuteAsync(string script, Dictionary <string, RuntimeValue> variables, Dictionary <string, RuntimeValue> parameters, string[] outVariables, string workingDirectory, CancellationToken cancellationToken) { using var runner = new PowerShellScriptRunner { DebugLogging = this.DebugLogging, VerboseLogging = this.VerboseLogging }; var outputData = new List <RuntimeValue>(); runner.MessageLogged += (s, e) => this.MessageLogged?.Invoke(this, e); if (this.LogOutput) { runner.OutputReceived += (s, e) => this.OutputReceived?.Invoke(this, e); } var outVariables2 = outVariables.ToDictionary(v => v, v => new RuntimeValue(string.Empty), StringComparer.OrdinalIgnoreCase); if (this.CollectOutput) { runner.OutputReceived += (s, e) => { var output = PSUtil.ToRuntimeValue(e.Output); lock (outputData) { outputData.Add(output); } }; } runner.ProgressUpdate += (s, e) => this.ProgressUpdate?.Invoke(this, e); int?exitCode = await runner.RunAsync(script, variables, parameters, outVariables2, workingDirectory, cancellationToken); return(new Result { ExitCode = exitCode, Output = outputData, OutVariables = outVariables2 }); }
public async Task <int?> RunAsync(string script, Dictionary <string, RuntimeValue> variables = null, Dictionary <string, RuntimeValue> parameters = null, Dictionary <string, RuntimeValue> outVariables = null, string workingDirectory = null, CancellationToken cancellationToken = default) { variables ??= new Dictionary <string, RuntimeValue>(); parameters ??= new Dictionary <string, RuntimeValue>(); outVariables ??= new Dictionary <string, RuntimeValue>(); var runspace = this.Runspace; var powerShell = System.Management.Automation.PowerShell.Create(); powerShell.Runspace = runspace; foreach (var var in variables) { this.LogDebug($"Importing {var.Key}..."); runspace.SessionStateProxy.SetVariable(var.Key, ConvertToPSValue(var.Value)); } if (this.DebugLogging) { runspace.SessionStateProxy.SetVariable("DebugPreference", "Continue"); } if (this.VerboseLogging) { runspace.SessionStateProxy.SetVariable("VerbosePreference", "Continue"); } var output = new PSDataCollection <PSObject>(); output.DataAdded += (s, e) => { var rubbish = output[e.Index]; this.OnOutputReceived(rubbish); }; powerShell.Streams.Progress.DataAdded += (s, e) => this.OnProgressUpdate(powerShell.Streams.Progress[e.Index]); powerShell.Streams.AttachLogging(this); if (!string.IsNullOrWhiteSpace(workingDirectory)) { DirectoryEx.Create(workingDirectory); powerShell.AddCommand("Set-Location"); powerShell.AddParameter("Path", workingDirectory); powerShell.AddStatement(); } powerShell.AddScript(script); foreach (var p in parameters) { this.LogDebug($"Assigning parameter {p.Key}..."); powerShell.AddParameter(p.Key, ConvertToPSValue(p.Value)); } int?exitCode = null; this.pshost.ShouldExit += handleShouldExit; using (var registration = cancellationToken.Register(powerShell.Stop)) { try { await Task.Factory.FromAsync(powerShell.BeginInvoke((PSDataCollection <PSObject>)null, output), powerShell.EndInvoke); foreach (var var in outVariables.Keys.ToList()) { outVariables[var] = PSUtil.ToRuntimeValue(unwrapReference(powerShell.Runspace.SessionStateProxy.GetVariable(var))); } } finally { this.pshost.ShouldExit -= handleShouldExit; } } void handleShouldExit(object s, ShouldExitEventArgs e) => exitCode = e.ExitCode; object unwrapReference(object value) => value is PSReference reference ? reference.Value : value; return(exitCode); }