public PSExecutionResults ExecuteScript(PSExecutionParameters parameters) { _logger.Information("Attemping to execute script"); if (!parameters.ScriptName.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase)) { parameters.ScriptName += ".ps1"; } if (!VaildPSScriptName.IsMatch(parameters.ScriptName)) { _logger.Error("Script name was not vaild"); return(new PSExecutionResults { Errors = new[] { "Script name is invalid" }, Completed = false }); } string safeFullPath = Directory.EnumerateFiles(_scriptPath, "*.ps1") .Where(x => Path.GetFileName(x).Equals(parameters.ScriptName, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); if (string.IsNullOrWhiteSpace(safeFullPath)) { _logger.Error("Script file was not found"); return(new PSExecutionResults { Errors = new[] { "Script file does not exist" }, Completed = false }); } _logger.Information("Setting up pipeline for {ScriptPath}", safeFullPath); RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration)) using (RunspaceInvoke runspaceInvoke = new RunspaceInvoke(runspace)) try { runspace.Open(); _logger.Information("Setting Execution Policy for process"); runspaceInvoke.Invoke("Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned"); using (Pipeline pipeline = runspace.CreatePipeline()) { RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); _logger.Information("Building script command"); Command scriptCommand = new Command(safeFullPath); if (parameters.Parameters != null && parameters.Parameters.Count > 0) { foreach (KeyValuePair <string, string> p in parameters.Parameters) { scriptCommand.Parameters.Add(new CommandParameter(p.Key, p.Value)); } } pipeline.Commands.Add(scriptCommand); try { _logger.Information("Invoking Script"); Collection <PSObject> results = pipeline.Invoke(); string[] errors = null; if (pipeline.Error.Count > 0) { Collection <ErrorRecord> pipelineErrors = pipeline.Error.Read() as Collection <ErrorRecord>; errors = pipelineErrors.Select(x => x.ToString()).ToArray(); } string[] output = results.Select(x => x.ToString()).ToArray(); _logger.Information("Script completed, {OutputCount} outputs, {ErrorCount} errors", output.Length, errors?.Length ?? 0); return(new PSExecutionResults { Output = output, Errors = errors, Completed = true }); } catch (RuntimeException re) { _logger.Error(re, "Runtime exception in pipeline, {ExceptionMessage}", re.Message); return(new PSExecutionResults { Errors = new[] { re.Message }, Completed = false }); } } } finally { runspace.Close(); } }
public PSExecutionResults ExecuteScript(PSExecutionParameters parameters) { _logger.Information("Attemping to execute script"); (string safeFullPath, string pathErrors) = _fileService.GetScript(parameters.ScriptName); if (!string.IsNullOrWhiteSpace(pathErrors)) { return(new PSExecutionResults { Errors = new[] { pathErrors }, Completed = false }); } if (string.IsNullOrWhiteSpace(safeFullPath)) { return(new PSExecutionResults { Errors = new[] { "Unknown error, path is empty" }, Completed = false }); } _logger.Information("Setting up pipeline for {ScriptPath}", safeFullPath); RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration)) using (RunspaceInvoke runspaceInvoke = new RunspaceInvoke(runspace)) try { runspace.Open(); ExecutionPolicy policy; if (string.IsNullOrWhiteSpace(parameters.ExecutionPolicy) || !Enum.TryParse(parameters.ExecutionPolicy, true, out policy)) { policy = DefaultExecutionPolicy; } _logger.Information("Setting Execution Policy for process to {ExecutionPolicy}", policy); runspaceInvoke.Invoke($"Set-ExecutionPolicy -Scope Process -ExecutionPolicy {policy}"); using (Pipeline pipeline = runspace.CreatePipeline()) { RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); _logger.Information("Building script command"); Command scriptCommand = new Command(safeFullPath); if (parameters.Parameters != null && parameters.Parameters.Count > 0) { foreach (KeyValuePair <string, string> p in parameters.Parameters) { scriptCommand.Parameters.Add(new CommandParameter(p.Key, p.Value)); } } pipeline.Commands.Add(scriptCommand); try { _logger.Information("Invoking Script"); Collection <PSObject> results = pipeline.Invoke(); string[] errors = null; if (pipeline.Error.Count > 0) { Collection <ErrorRecord> pipelineErrors = pipeline.Error.Read() as Collection <ErrorRecord>; errors = pipelineErrors.Select(x => x.ToString()).ToArray(); } string[] output = results.Select(x => x.ToString()).ToArray(); _logger.Information("Script completed, {OutputCount} outputs, {ErrorCount} errors", output.Length, errors?.Length ?? 0); return(new PSExecutionResults { Output = output, Errors = errors, Completed = true }); } catch (RuntimeException re) { _logger.Error(re, "Runtime exception in pipeline, {ExceptionMessage}", re.Message); return(new PSExecutionResults { Errors = new[] { re.Message }, Completed = false }); } } } finally { runspace.Close(); } }