Ejemplo n.º 1
0
            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
                });
            }
Ejemplo n.º 2
0
        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);
        }