private void HandleJobOutput(Job job, TSession sessionForJob, bool discardNonPipelineResults, Action <PSObject> outputAction) { Action <PSObject> processOutput = delegate(PSObject pso) { if ((pso != null) && (outputAction != null)) { outputAction(pso); } }; job.Output.DataAdded += delegate(object sender, DataAddedEventArgs eventArgs) { PSDataCollection <PSObject> datas = (PSDataCollection <PSObject>)sender; if (discardNonPipelineResults) { foreach (PSObject obj2 in datas.ReadAll()) { processOutput(obj2); } } else { PSObject obj3 = datas[eventArgs.Index]; processOutput(obj3); } }; if (discardNonPipelineResults) { SessionBasedCmdletAdapter <TObjectInstance, TSession> .DiscardJobOutputs(job, JobOutputs.Progress | JobOutputs.Debug | JobOutputs.Verbose | JobOutputs.Warning | JobOutputs.Error); } }
private IEnumerable <T> ExecuteCommandInDebugger <T>(PSCommand command, bool redirectOutput) { var outputCollection = new PSDataCollection <PSObject>(); if (redirectOutput) { outputCollection.DataAdded += (sender, args) => { // Stream script output to console. Execute.OnUIThread(() => { var output = IoC.Get <IOutput>(); foreach (var item in outputCollection.ReadAll()) { output.AppendLine(item.ToString()); } }); }; } _runspace.Debugger.ProcessCommand( command, outputCollection); return (outputCollection .Select(pso => pso.ImmediateBaseObject) .Cast <T>()); }
/// <summary> /// Executes a powershell script /// </summary> /// <param name="folder">Folder where to execute the script</param> /// <param name="script">Script to execute</param> /// <param name="log">Logger to use</param> /// <param name="parameters">Parameters for the script</param> public static void ExecuteScript(string folder, string script, ILogger log, Dictionary <string, string> parameters) { using (PowerShell PowerShellInstance = PowerShell.Create()) { PowerShellInstance.Runspace.SessionStateProxy.Path.SetLocation(folder); // use "AddScript" to add the contents of a script file to the end of the execution pipeline. // use "AddCommand" to add individual commands/cmdlets to the end of the execution pipeline. PowerShellInstance.AddScript("function write-host($out) {write-output $out}").Invoke(); PowerShellInstance.Commands.Clear(); PowerShellInstance.AddScript(script); foreach (var param in parameters.Keys) { PowerShellInstance.AddParameter(param, parameters[param]); PowerShellInstance.Runspace.SessionStateProxy.SetVariable(param, parameters[param]); } PowerShellInstance.AddParameter("-Verb", "RunAs"); Collection <PSObject> results = new Collection <PSObject>(); try { PSDataCollection <PSObject> output = new PSDataCollection <PSObject>(); output.DataAdded += (sender, e) => { PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> res = myp.ReadAll(); foreach (PSObject result in res) { log.Log(result.ToString(), false); } }; PowerShellInstance.Streams.Error.DataAdded += (sender, e) => { var newRecord = ((PSDataCollection <ErrorRecord>)sender)[e.Index]; log.Log(newRecord.ToString(), true); }; PowerShellInstance.Streams.Debug.DataAdded += (sender, e) => { var newRecord = ((PSDataCollection <DebugRecord>)sender)[e.Index]; log.Log(newRecord.ToString(), false); }; PowerShellInstance.Streams.Verbose.DataAdded += (sender, e) => { var newRecord = ((PSDataCollection <VerboseRecord>)sender)[e.Index]; log.Log(newRecord.ToString(), false); }; PowerShellInstance.Streams.Warning.DataAdded += (sender, e) => { var newRecord = ((PSDataCollection <WarningRecord>)sender)[e.Index]; log.Log(newRecord.ToString(), false); }; PowerShellInstance.Invoke <PSObject, PSObject>(null, output, new PSInvocationSettings() { }); }catch (RuntimeException e) { log.Log(e.Message, true); } } }
/// <summary> /// Event handler for when data is added to the output stream. /// </summary> /// <param name="sender">Contains the complete PSDataCollection of all output items.</param> /// <param name="e">Contains the index ID of the added collection item and the ID of the PowerShell instance this event belongs to.</param> void outputCollection_DataAdded(object sender, DataAddedEventArgs e) { PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> results = myp.ReadAll(); foreach (PSObject result in results) { Console.WriteLine(result.ToString()); } }
internal Pipeline CreatePipeline(string line, bool addToHistory, bool useNestedPipelines) { Pipeline pipeline = null; EventHandler <DataAddedEventArgs> handler = null; if (this.IsRunspaceOverridden) { if (((this._runspaceRef.Value is RemoteRunspace) && !string.IsNullOrEmpty(line)) && string.Equals(line.Trim(), "exit", StringComparison.OrdinalIgnoreCase)) { line = "Exit-PSSession"; } PSCommand command = this.ParsePsCommandUsingScriptBlock(line, null); if (command != null) { pipeline = useNestedPipelines ? this._runspaceRef.Value.CreateNestedPipeline(command.Commands[0].CommandText, addToHistory) : this._runspaceRef.Value.CreatePipeline(command.Commands[0].CommandText, addToHistory); pipeline.Commands.Clear(); foreach (Command command2 in command.Commands) { pipeline.Commands.Add(command2); } } } if (pipeline == null) { pipeline = useNestedPipelines ? this._runspaceRef.Value.CreateNestedPipeline(line, addToHistory) : this._runspaceRef.Value.CreatePipeline(line, addToHistory); } RemotePipeline pipeline2 = pipeline as RemotePipeline; if (this.IsRunspaceOverridden && (pipeline2 != null)) { PowerShell powerShell = pipeline2.PowerShell; if (powerShell.RemotePowerShell != null) { powerShell.RemotePowerShell.RCConnectionNotification += new EventHandler <PSConnectionRetryStatusEventArgs>(this.HandleRCConnectionNotification); } if (handler == null) { handler = delegate(object sender, DataAddedEventArgs eventArgs) { RemoteRunspace runspace = this._runspaceRef.Value as RemoteRunspace; PSDataCollection <ErrorRecord> datas = sender as PSDataCollection <ErrorRecord>; if (((runspace != null) && (datas != null)) && (runspace.RunspacePool.RemoteRunspacePoolInternal.Host != null)) { foreach (ErrorRecord record in datas.ReadAll()) { runspace.RunspacePool.RemoteRunspacePoolInternal.Host.UI.WriteErrorLine(record.ToString()); } } }; } powerShell.ErrorBuffer.DataAdded += handler; } pipeline.SetHistoryString(line); return(pipeline); }
private void outputCollection_DataAdded(object sender, DataAddedEventArgs e) { PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> results = myp.ReadAll(); foreach (PSObject result in results) { _callback(result + Environment.NewLine); } }
private void Error_DataAdded(object sender, DataAddedEventArgs e) { PSDataCollection <ErrorRecord> myp = (PSDataCollection <ErrorRecord>)sender; Collection <ErrorRecord> errors = myp.ReadAll(); foreach (ErrorRecord error in errors) { _callback(error + Environment.NewLine); } }
private void Output_DataAdded(object sender, DataAddedEventArgs e) { PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> results = myp.ReadAll(); foreach (PSObject result in results) { UpdateResultValue(result.ToString()); } }
private void PSOutput_DataAdded(object sender, DataAddedEventArgs e) { Debug.WriteLine("[DEBUG] New Results Added"); PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> results = myp.ReadAll(); foreach (PSObject result in results) { this.host.UI.WriteLine(result.ToString()); } }
protected override void EndProcessing() { var searchParams = new Dictionary <string, object>(SearchParamNames.Length) { { "AsArray", true } }; var bound = MyInvocation.BoundParameters; foreach (var sp in SearchParamNames) { if (bound.TryGetValue(sp, out object val)) { searchParams.Add(sp == nameof(CaseSensitiveSearch) ? "CaseSenitive" : sp, val); bound.Remove(sp); } } if (bound.TryGetValue(nameof(CaseSensitivePattern), out var cs)) { bound.Add("CaseSensitive", cs); bound.Remove(nameof(CaseSensitivePattern)); } var slsParams = bound; using (_powershell = PowerShell.Create(RunspaceMode.CurrentRunspace)) { _powershell.AddCommand("Search-Everything").AddParameters(searchParams); var paths = _powershell.Invoke <string[]>().First(); if (_powershell.HadErrors) { foreach (var e in _powershell.Streams.Error.ReadAll()) { WriteError(e); } } if (paths.Length == 0) { WriteWarning("No files in search result."); return; } _powershell.Commands.Clear(); slsParams.Add("LiteralPath", paths); _powershell.AddCommand("Microsoft.PowerShell.Utility\\Select-String").AddParameters(slsParams); PSDataCollection <PSObject> output = new PSDataCollection <PSObject>(); output.DataAdded += (sender, args) => { WriteObject(output.ReadAll(), true); }; _powershell.Invoke(null, output); } _powershell = null; }
/// <summary> /// Method to run the sample script and handle debugger events. /// </summary> public void RunFile(string filePath) { using (Runspace runspace = RunspaceFactory.CreateRunspace()) { runspace.Open(); runspace.Debugger.SetDebugMode(DebugModes.LocalScript); using (PowerShell powerShell = PowerShell.Create()) { powerShell.Runspace = runspace; runspace.Debugger.BreakpointUpdated += HandlerBreakpointUpdatedEvent; runspace.Debugger.DebuggerStop += HandleDebuggerStopEvent; UserIOImpl.PrintMessage("Starting script file: " + filePath); powerShell.AddStatement().AddCommand("Set-PSBreakpoint").AddParameter("Script", filePath).AddParameter("Line", 1); foreach (var kv in VariableReplaceMap) { UserIOImpl.PrintMessage("Setting variable breakpoint on: " + kv.Key); powerShell.AddStatement().AddCommand("Set-PSBreakpoint").AddParameter("Variable", kv.Key); } powerShell.AddStatement().AddCommand("Set-ExecutionPolicy").AddParameter("ExecutionPolicy", "Bypass").AddParameter("Scope", "CurrentUser"); powerShell.AddScript(filePath); var scriptOutput = new PSDataCollection <PSObject>(); scriptOutput.DataAdded += (sender, args) => { foreach (var item in scriptOutput.ReadAll()) { UserIOImpl.PrintMessage("| " + item); } }; powerShell.Invoke <PSObject>(null, scriptOutput); if (powerShell.Streams.Error != null) { foreach (ErrorRecord errorRecord in powerShell.Streams.Error.ReadAll()) { if (errorRecord != null && errorRecord.ErrorDetails != null) { UserIOImpl.PrintMessage(errorRecord.ErrorDetails.Message); } } } } } }
private Collection <T> ReadAll <T>(PSDataCollection <T> psDataCollection) { if (this.flush) { return(psDataCollection.ReadAll()); } T[] array = new T[psDataCollection.Count]; psDataCollection.CopyTo(array, 0); Collection <T> collection = new Collection <T>(); foreach (T local in array) { collection.Add(local); } return(collection); }
/** * <summary> * Gera a saÃda em texto. * <para><paramref name="Comando"/> - Comando que será executado no espaço do powershell</para> * <para>Método SÃncrono</para> * </summary> */ public void BeginInvoke_Saida(object sender, DataAddedEventArgs e) { try { PSDataCollection <PSObject> Conversor = (PSDataCollection <PSObject>)sender; Collection <PSObject> OutComandos_Script = Conversor.ReadAll(); foreach (var i in OutComandos_Script) { Result += i.BaseObject.ToString(); //pode gerr conflitos em outros geradores, cuidado! } } catch (Exception ex) { TratadorErros(ex, this.GetType().Name); } }
// Method to handle the Debugger DebuggerStop event. // The debugger will remain in debugger stop mode until this event // handler returns, at which time DebuggerStopEventArgs.ResumeAction should // be set to indicate how the debugger should proceed (Continue, StepInto, // StepOut, StepOver, Stop). // This handler should run a REPL (Read Evaluate Print Loop) to allow user // to investigate the state of script execution, by processing user commands // with the Debugger.ProcessCommand method. If a user command releases the // debugger then the DebuggerStopEventArgs.ResumeAction is set and this // handler returns. private void HandleDebuggerStopEvent(object sender, DebuggerStopEventArgs args) { Debugger debugger = sender as Debugger; DebuggerResumeAction?resumeAction = null; // Display messages pertaining to this debugger stop. WriteDebuggerStopMessages(args); // Simple REPL (Read Evaluate Print Loop) to process // Debugger commands. while (resumeAction == null) { // Write debug prompt. Console.Write("[DBG] PS >> "); string command = Console.ReadLine(); Console.WriteLine(); // Stream output from command processing to console. var output = new PSDataCollection <PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { Console.WriteLine(item); } }; // Process command. // The Debugger.ProcesCommand method will parse and handle debugger specific // commands such as 'h' (help), 'list', 'stepover', etc. If the command is // not specific to the debugger then it will be evaluated as a PowerShell // command or script. The returned DebuggerCommandResults object will indicate // whether the command was evaluated by the debugger and if the debugger should // be released with a specific resume action. PSCommand psCommand = new PSCommand(); psCommand.AddScript(command).AddCommand("Out-String").AddParameter("Stream", true); DebuggerCommandResults results = debugger.ProcessCommand(psCommand, output); if (results.ResumeAction != null) { resumeAction = results.ResumeAction; } } // Return from event handler with user resume action. args.ResumeAction = resumeAction.Value; }
private void AggregateJobResults(PSDataCollection <PSStreamObject> resultsCollection) { lock (_myLock) { // try not to remove results from a job, unless it seems safe ... if (_disposed || _stoppedMonitoringAllJobs || _aggregatedResults.IsAddingCompleted || _cancellationTokenSource.IsCancellationRequested) { return; } } // ... and after removing the results via ReadAll, we have to make sure that we don't drop them ... foreach (var result in resultsCollection.ReadAll()) { bool successfullyAggregatedResult = false; try { lock (_myLock) { // try not to remove results from a job, unless it seems safe ... if (!(_disposed || _stoppedMonitoringAllJobs || _aggregatedResults.IsAddingCompleted || _cancellationTokenSource.IsCancellationRequested)) { _aggregatedResults.Add(result, _cancellationTokenSource.Token); successfullyAggregatedResult = true; } } } catch (Exception) // BlockingCollection.Add can throw undocumented exceptions - we cannot just catch InvalidOperationException { } // ... so if _aggregatedResults is not accepting new results, we will store them in the throttling job if (!successfullyAggregatedResult) { this.StopMonitoringJob(_throttlingJob); try { _throttlingJob.Results.Add(result); } catch (InvalidOperationException) { Dbg.Assert(false, "ThrottlingJob.Results was already closed when trying to preserve results aggregated by ForwardingHelper"); } } } }
private DebuggerCommandResults RunDebuggerCommand(Debugger debugger, string command) { var output = new PSDataCollection <PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { UserIOImpl.PrintMessage(item.ToString() + "\n"); } }; PSCommand psCommand = new PSCommand(); psCommand.AddScript(command); DebuggerCommandResults results = debugger.ProcessCommand(psCommand, output); return(results); }
void outputCollection_DataAdded(object sender, DataAddedEventArgs e) { tb_Out.Dispatcher.Invoke(() => { Collection <PSObject> curr = outputCollection.ReadAll(); foreach (PSObject r in curr) { tb_Out.Text += "\n" + r.ToString(); if (r.ToString().Contains("av01")) { cb_AV1.IsChecked = true; tb_Out.Text += "\n" + "↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑~AV1~"; } tb_Out.ScrollToEnd(); } } ); }
/// <summary> /// The output data added event handler. This event is called when /// data is added to the output pipe. It reads the data that is /// available and displays it on the console. /// </summary> /// <param name="sender">The output pipe this event is associated with.</param> /// <param name="e">Parameter is not used.</param> private void Output_DataAdded(object sender, DataAddedEventArgs e) { PSDataCollection <PSObject> myp = (PSDataCollection <PSObject>)sender; Collection <PSObject> results = myp.ReadAll(); foreach (PSObject result in results) { //Console.WriteLine(result.ToString()); Dispatcher.BeginInvoke(new Action(() => { try { txtInstallStatusVerbose.Text = txtInstallStatusVerbose.Text + lineBreak + result.ToString(); } catch (Exception ex) { txtInstallStatusErrors.Text = txtInstallStatusErrors.Text + lineBreak + "Error: " + ex.Message; } outputVerbose.ScrollToBottom(); }), DispatcherPriority.ContextIdle); } }
private void HandlePowerShellPStreamItem(PSStreamObject streamItem) { if (!_debugger.InBreakpoint) { // First write any accumulated items. foreach (var item in _debugAccumulateCollection.ReadAll()) { AddToDebugBlockingCollection(item); } // Handle new item. if ((_debugBlockingCollection != null) && (_debugBlockingCollection.IsOpen)) { AddToDebugBlockingCollection(streamItem); } } else if (_debugAccumulateCollection.IsOpen) { // Add to accumulator if debugger is stopped in breakpoint. _debugAccumulateCollection.Add(streamItem); } }
private async Task <IEnumerable <T> > ExecuteCommand <T>(PSCommand command, bool redirectOutput = false) { var result = default(IEnumerable <T>); if (Thread.CurrentThread.ManagedThreadId != _pipelineThreadId && _pipelineExecutionTask != null) { // Queue the execution since one task is already running. var executionRequest = new PipelineExecutionRequest <T>(this, command, redirectOutput); _pipelineResultTask = new TaskCompletionSource <IPipelineExecutionRequest>(); if (_pipelineExecutionTask.TrySetResult(executionRequest)) { await _pipelineResultTask.Task; return(executionRequest.Results); } return(null); } var scriptOutput = new PSDataCollection <PSObject>(); if (redirectOutput) { scriptOutput.DataAdded += (sender, args) => { // Stream script output to console. Execute.OnUIThread(() => { var output = IoC.Get <IOutput>(); foreach (var item in scriptOutput.ReadAll()) { output.AppendLine(item.ToString()); } }); }; } if (_runspace.RunspaceAvailability == RunspaceAvailability.AvailableForNestedCommand || _debuggerExecutionTask != null) { result = ExecuteCommandInDebugger <T>(command, redirectOutput); } else { result = await Task.Factory.StartNew <IEnumerable <T> >(() => { _powerShell.Commands = command; var executionResult = _powerShell.Invoke <T>(scriptOutput); return(executionResult); }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default ); } _powerShell?.Commands.Clear(); if (_powerShell == null || _powerShell.HadErrors) { return(null); } return(result); }
/// <summary> /// Default constructor for creating ServerPowerShellDrivers /// </summary> /// <param name="powershell">decoded powershell object</param> /// <param name="extraPowerShell">extra pipeline to be run after <paramref name="powershell"/> completes</param> /// <param name="noInput">whether there is input for this powershell</param> /// <param name="clientPowerShellId">the client powershell id</param> /// <param name="clientRunspacePoolId">the client runspacepool id</param> /// <param name="runspacePoolDriver">runspace pool driver /// which is creating this powershell driver</param> /// <param name="apartmentState">apartment state for this powershell</param> /// <param name="hostInfo">host info using which the host for /// this powershell will be constructed</param> /// <param name="streamOptions">serialization options for the streams in this powershell</param> /// <param name="addToHistory"> /// true if the command is to be added to history list of the runspace. false, otherwise. /// </param> /// <param name="rsToUse"> /// If not null, this Runspace will be used to invoke Powershell. /// If null, the RunspacePool pointed by <paramref name="runspacePoolDriver"/> will be used. /// </param> /// <param name="output"> /// If not null, this is used as another source of output sent to the client. /// </param> internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId, Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions, bool addToHistory, Runspace rsToUse, PSDataCollection<PSObject> output) #endif { InstanceId = clientPowerShellId; RunspacePoolId = clientRunspacePoolId; RemoteStreamOptions = streamOptions; #if !CORECLR // No ApartmentState In CoreCLR this.apartmentState = apartmentState; #endif LocalPowerShell = powershell; _extraPowerShell = extraPowerShell; _localPowerShellOutput = new PSDataCollection<PSObject>(); _noInput = noInput; _addToHistory = addToHistory; _psDriverInvoker = runspacePoolDriver; DataStructureHandler = runspacePoolDriver.DataStructureHandler.CreatePowerShellDataStructureHandler(clientPowerShellId, clientRunspacePoolId, RemoteStreamOptions, LocalPowerShell); _remoteHost = DataStructureHandler.GetHostAssociatedWithPowerShell(hostInfo, runspacePoolDriver.ServerRemoteHost); if (!noInput) { InputCollection = new PSDataCollection<object>(); InputCollection.ReleaseOnEnumeration = true; InputCollection.IdleEvent += new EventHandler<EventArgs>(HandleIdleEvent); } RegisterPipelineOutputEventHandlers(_localPowerShellOutput); if (LocalPowerShell != null) { RegisterPowerShellEventHandlers(LocalPowerShell); _datasent[0] = false; } if (extraPowerShell != null) { RegisterPowerShellEventHandlers(extraPowerShell); _datasent[1] = false; } RegisterDataStructureHandlerEventHandlers(DataStructureHandler); // set the runspace pool and invoke this powershell if (null != rsToUse) { LocalPowerShell.Runspace = rsToUse; if (extraPowerShell != null) { extraPowerShell.Runspace = rsToUse; } } else { LocalPowerShell.RunspacePool = runspacePoolDriver.RunspacePool; if (extraPowerShell != null) { extraPowerShell.RunspacePool = runspacePoolDriver.RunspacePool; } } if (output != null) { output.DataAdded += (sender, args) => { if (_localPowerShellOutput.IsOpen) { var items = output.ReadAll(); foreach (var item in items) { _localPowerShellOutput.Add(item); } } }; } }
private bool CheckVariables(Debugger debugger) { bool updatedVariable = false; var processVariables = new PSDataCollection <PSObject>(); processVariables.DataAdded += (dSender, dArgs) => { foreach (PSObject item in processVariables.ReadAll()) { if (item.ImmediateBaseObject is PSVariable) { PSVariable psv = (PSVariable)item.ImmediateBaseObject; if ( !VariableMap.ContainsKey(psv.Name) || ( VariableMap[psv.Name] != null && VariableMap[psv.Name].ToString() != psv.Value.ToString() ) ) { DumpVariable(psv.Name, psv.Value); } if (VariableReplaceMap != null && VariableReplaceMap.ContainsKey(psv.Name)) { if (psv.Value.ToString() != VariableReplaceMap[psv.Name]) { UserIOImpl.PrintMessage(@"Updated variable " + psv.Name + ": " + psv.Value + " --> " + VariableReplaceMap[psv.Name], "Red"); psv.Value = VariableReplaceMap[psv.Name]; updatedVariable = true; } } VariableMap[psv.Name] = psv.Value; } else if (item.ImmediateBaseObject is ErrorRecord) { ErrorRecord errorRecord = (ErrorRecord)item.ImmediateBaseObject; UserIOImpl.PrintMessage(@"* item: " + item.ImmediateBaseObject.GetType() + "\n"); if (errorRecord != null && errorRecord.ErrorDetails != null) { UserIOImpl.PrintMessage(errorRecord.ErrorDetails.Message + "\n"); } } else { UserIOImpl.PrintMessage(@"* item: " + item.ImmediateBaseObject.GetType()); } } }; PSCommand psCommand = new PSCommand(); psCommand.AddScript("Get-Variable"); DebuggerCommandResults results = debugger.ProcessCommand(psCommand, processVariables); return(updatedVariable); }
/// <summary> /// Method to run the sample script and handle debugger events. /// </summary> public void Run() { Console.WriteLine("Starting PowerShell Debugger Sample"); Console.WriteLine(); // Create sample script file to debug. string fileName = "PowerShellSDKDebuggerSample.ps1"; string filePath = System.IO.Path.Combine(Environment.CurrentDirectory, fileName); System.IO.File.WriteAllText(filePath, _script); using (Runspace runspace = RunspaceFactory.CreateRunspace()) { // Open runspace and set debug mode to debug PowerShell scripts and // Workflow scripts. PowerShell script debugging is enabled by default, // Workflow debugging is opt-in. runspace.Open(); runspace.Debugger.SetDebugMode(DebugModes.LocalScript); using (PowerShell powerShell = PowerShell.Create()) { powerShell.Runspace = runspace; // Set breakpoint update event handler. The breakpoint update event is // raised whenever a break point is added, removed, enabled, or disabled. // This event is generally used to display current breakpoint information. runspace.Debugger.BreakpointUpdated += HandlerBreakpointUpdatedEvent; // Set debugger stop event handler. The debugger stop event is raised // whenever a breakpoint is hit, or for each script execution sequence point // when the debugger is in step mode. The debugger remains stopped at the // current execution location until the event handler returns. When the // event handler returns it should set the DebuggerStopEventArgs.ResumeAction // to indicate how the debugger should proceed: // - Continue Continue execution until next breakpoint is hit. // - StepInto Step into function. // - StepOut Step out of function. // - StepOver Step over function. // - Stop Stop debugging. runspace.Debugger.DebuggerStop += HandleDebuggerStopEvent; // Set initial breakpoint on line 10 of script. This breakpoint // will be in the script workflow function. powerShell.AddCommand("Set-PSBreakpoint").AddParameter("Script", filePath).AddParameter("Line", 10); powerShell.Invoke(); Console.WriteLine("Starting script file: " + filePath); Console.WriteLine(); // Run script file. powerShell.Commands.Clear(); powerShell.AddScript(filePath).AddCommand("Out-String").AddParameter("Stream", true); var scriptOutput = new PSDataCollection<PSObject>(); scriptOutput.DataAdded += (sender, args) => { // Stream script output to console. foreach (var item in scriptOutput.ReadAll()) { Console.WriteLine(item); } }; powerShell.Invoke<PSObject>(null, scriptOutput); } } // Delete the sample script file. if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } Console.WriteLine("PowerShell Debugger Sample Complete"); Console.WriteLine(); Console.WriteLine("Press any key to exit."); Console.ReadKey(true); }
private void DebuggerOnDebuggerStop(object sender, DebuggerStopEventArgs args) { Debugger debugger = sender as Debugger; DebuggerResumeAction?resumeAction = null; DebuggingInBreakpoint = true; try { if ( ((ScriptingHostUserInterface)host.UI).CheckSessionCanDoInteractiveAction( nameof(DebuggerOnDebuggerStop))) { var output = new PSDataCollection <PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { host.UI.WriteLine(item.ToString()); } }; var message = Message.Parse(this, "ise:breakpointhit"); //var position = args.InvocationInfo.DisplayScriptPosition; IScriptExtent position; try { position = args.InvocationInfo.GetType() .GetProperty("ScriptPosition", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty) .GetValue(args.InvocationInfo) as IScriptExtent; } catch (Exception) { position = args.InvocationInfo.DisplayScriptPosition; } if (position != null) { message.Arguments.Add("Line", (position.StartLineNumber - 1).ToString()); message.Arguments.Add("Column", (position.StartColumnNumber - 1).ToString()); message.Arguments.Add("EndLine", (position.EndLineNumber - 1).ToString()); message.Arguments.Add("EndColumn", (position.EndColumnNumber - 1).ToString()); } else { message.Arguments.Add("Line", (args.InvocationInfo.ScriptLineNumber - 1).ToString()); message.Arguments.Add("Column", (args.InvocationInfo.OffsetInLine - 1).ToString()); message.Arguments.Add("EndLine", (args.InvocationInfo.ScriptLineNumber).ToString()); message.Arguments.Add("EndColumn", (0).ToString()); } message.Arguments.Add("HitCount", args.Breakpoints.Count > 0 ? args.Breakpoints[0].HitCount.ToString() : "1"); SendUiMessage(message); while (resumeAction == null && !abortRequested) { if (ImmediateCommand != null) { var psCommand = new PSCommand(); psCommand.AddScript(ImmediateCommand as string) .AddCommand("Out-Default"); //.AddParameter("Stream", true); var results = debugger?.ProcessCommand(psCommand, output); ImmediateResults = output; if (results?.ResumeAction != null) { resumeAction = results.ResumeAction; } ImmediateCommand = null; } else { Thread.Sleep(20); } } args.ResumeAction = resumeAction ?? DebuggerResumeAction.Continue; } } finally { DebuggingInBreakpoint = false; } }
private void AggregateJobResults(PSDataCollection<PSStreamObject> resultsCollection) { lock (_myLock) { // try not to remove results from a job, unless it seems safe ... if (_disposed || _stoppedMonitoringAllJobs || _aggregatedResults.IsAddingCompleted || _cancellationTokenSource.IsCancellationRequested) { return; } } // ... and after removing the results via ReadAll, we have to make sure that we don't drop them ... foreach (var result in resultsCollection.ReadAll()) { bool successfullyAggregatedResult = false; try { lock (_myLock) { // try not to remove results from a job, unless it seems safe ... if (!(_disposed || _stoppedMonitoringAllJobs || _aggregatedResults.IsAddingCompleted || _cancellationTokenSource.IsCancellationRequested)) { _aggregatedResults.Add(result, _cancellationTokenSource.Token); successfullyAggregatedResult = true; } } } catch (Exception) // BlockingCollection.Add can throw undocumented exceptions - we cannot just catch InvalidOperationException { } // ... so if _aggregatedResults is not accepting new results, we will store them in the throttling job if (!successfullyAggregatedResult) { this.StopMonitoringJob(_throttlingJob); try { _throttlingJob.Results.Add(result); } catch (InvalidOperationException) { Dbg.Assert(false, "ThrottlingJob.Results was already closed when trying to preserve results aggregated by ForwardingHelper"); } } } }
public BuildResult Build(Build build) { using (var powerShellInstance = PowerShell.Create()) { powerShellInstance.AddScript($"cd \"{ScriptsPath}\";npm run build;"); PSDataCollection <PSObject> outputCollection = new PSDataCollection <PSObject>(); // the streams (Error, Debug, Progress, etc) are available on the PowerShell instance. // we can review them during or after execution. // we can also be notified when a new item is written to the stream (like this): powerShellInstance.Streams.Error.DataAdded += ErrorDataAdded; powerShellInstance.Streams.Debug.DataAdded += OutputCollectionDataAdded; powerShellInstance.Streams.Information.DataAdded += OutputCollectionDataAdded; powerShellInstance.Streams.Progress.DataAdded += OutputCollectionDataAdded; powerShellInstance.Streams.Verbose.DataAdded += OutputCollectionDataAdded; powerShellInstance.Streams.Warning.DataAdded += OutputCollectionDataAdded; // begin invoke execution on the pipeline // use this overload to specify an output stream buffer IAsyncResult result = powerShellInstance.BeginInvoke <PSObject, PSObject>(null, outputCollection); while (!result.IsCompleted) { // might want to place a timeout here... } foreach (var outputItem in outputCollection.ReadAll()) { successList.AppendLine(outputItem.BaseObject.ToString()); } //update build log build.BuildLog = successList.ToString(); BuildRepository.Update(build); return(new BuildResult { ErrorText = errorsList.ToString(), SuccessText = successList.ToString(), IsSuccess = isSuccess }); } void OutputCollectionDataAdded(object sender, DataAddedEventArgs e) { using (var dataList = (PSDataCollection <PSObject>)sender) { foreach (var data in dataList.ReadAll()) { successList.AppendLine(data.ToString()); } } // do something when an object is written to the output stream Console.WriteLine("Object added to output."); } void ErrorDataAdded(object sender, DataAddedEventArgs e) { using (var errorDataList = (PSDataCollection <ErrorRecord>)sender) { foreach (var errorData in errorDataList.ReadAll()) { errorsList.AppendLine(errorData.ToString()); } isSuccess = false; } } }
private void DebuggerOnDebuggerStop(object sender, DebuggerStopEventArgs args) { Debugger debugger = sender as Debugger; DebuggerResumeAction? resumeAction = null; DebuggingInBreakpoint = true; try { if ( ((ScriptingHostUserInterface) host.UI).CheckSessionCanDoInteractiveAction( nameof(DebuggerOnDebuggerStop))) { var output = new PSDataCollection<PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { host.UI.WriteLine(item.ToString()); } }; var message = Message.Parse(this, "ise:breakpointhit"); //var position = args.InvocationInfo.DisplayScriptPosition; IScriptExtent position; try { position = args.InvocationInfo.GetType() .GetProperty("ScriptPosition", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty) .GetValue(args.InvocationInfo) as IScriptExtent; } catch (Exception) { position = args.InvocationInfo.DisplayScriptPosition; } if (position != null) { message.Arguments.Add("Line", (position.StartLineNumber - 1).ToString()); message.Arguments.Add("Column", (position.StartColumnNumber - 1).ToString()); message.Arguments.Add("EndLine", (position.EndLineNumber - 1).ToString()); message.Arguments.Add("EndColumn", (position.EndColumnNumber - 1).ToString()); } else { message.Arguments.Add("Line", (args.InvocationInfo.ScriptLineNumber - 1).ToString()); message.Arguments.Add("Column", (args.InvocationInfo.OffsetInLine - 1).ToString()); message.Arguments.Add("EndLine", (args.InvocationInfo.ScriptLineNumber).ToString()); message.Arguments.Add("EndColumn", (0).ToString()); } message.Arguments.Add("HitCount", args.Breakpoints.Count > 0 ? args.Breakpoints[0].HitCount.ToString() : "1"); SendUiMessage(message); while (resumeAction == null && !abortRequested) { if (ImmediateCommand != null) { var psCommand = new PSCommand(); psCommand.AddScript(ImmediateCommand as string) .AddCommand("Out-Default"); //.AddParameter("Stream", true); var results = debugger?.ProcessCommand(psCommand, output); ImmediateResults = output; if (results?.ResumeAction != null) { resumeAction = results.ResumeAction; } ImmediateCommand = null; } else { Thread.Sleep(20); } } args.ResumeAction = resumeAction ?? DebuggerResumeAction.Continue; } } finally { DebuggingInBreakpoint = false; } }
private void AggregateJobResults(PSDataCollection<PSStreamObject> resultsCollection) { lock (this._myLock) { if ((this._disposed || this._stoppedMonitoringAllJobs) || (this._aggregatedResults.IsAddingCompleted || this._cancellationTokenSource.IsCancellationRequested)) { return; } } foreach (PSStreamObject obj2 in resultsCollection.ReadAll()) { bool flag = false; try { lock (this._myLock) { if ((!this._disposed && !this._stoppedMonitoringAllJobs) && (!this._aggregatedResults.IsAddingCompleted && !this._cancellationTokenSource.IsCancellationRequested)) { this._aggregatedResults.Add(obj2, this._cancellationTokenSource.Token); flag = true; } } } catch (Exception) { } if (!flag) { this.StopMonitoringJob(this._throttlingJob); try { this._throttlingJob.Results.Add(obj2); } catch (InvalidOperationException) { } } } }
/// <summary> /// ProcessCommand /// </summary> /// <param name="command">PowerShell command</param> /// <param name="output">Output</param> /// <returns>DebuggerCommandResults</returns> public override DebuggerCommandResults ProcessCommand(PSCommand command, PSDataCollection<PSObject> output) { if (command == null) { throw new PSArgumentNullException("command"); } if (output == null) { throw new PSArgumentNullException("output"); } if (!DebuggerStopped) { throw new PSInvalidOperationException( DebuggerStrings.CannotProcessDebuggerCommandNotStopped, null, Debugger.CannotProcessCommandNotStopped, ErrorCategory.InvalidOperation, null); } // // Allow an active pushed debugger to process commands // DebuggerCommandResults results = ProcessCommandForActiveDebugger(command, output); if (results != null) { return results; } // // Otherwise let root script debugger handle it. // LocalRunspace localRunspace = _context.CurrentRunspace as LocalRunspace; if (localRunspace == null) { throw new PSInvalidOperationException( DebuggerStrings.CannotProcessDebuggerCommandNotStopped, null, Debugger.CannotProcessCommandNotStopped, ErrorCategory.InvalidOperation, null); } try { using (_psDebuggerCommand = PowerShell.Create()) { if (localRunspace.GetCurrentlyRunningPipeline() != null) { _psDebuggerCommand.SetIsNested(true); } _psDebuggerCommand.Runspace = localRunspace; _psDebuggerCommand.Commands = command; foreach (var cmd in _psDebuggerCommand.Commands.Commands) { cmd.MergeMyResults(PipelineResultTypes.All, PipelineResultTypes.Output); } PSDataCollection<PSObject> internalOutput = new PSDataCollection<PSObject>(); internalOutput.DataAdded += (sender, args) => { foreach (var item in internalOutput.ReadAll()) { if (item == null) { continue; } DebuggerCommand dbgCmd = item.BaseObject as DebuggerCommand; if (dbgCmd != null) { bool executedByDebugger = (dbgCmd.ResumeAction != null || dbgCmd.ExecutedByDebugger); results = new DebuggerCommandResults(dbgCmd.ResumeAction, executedByDebugger); } else { output.Add(item); } } }; // Allow any exceptions to propagate. _psDebuggerCommand.InvokeWithDebugger(null, internalOutput, null, false); } } finally { _psDebuggerCommand = null; } return results ?? new DebuggerCommandResults(null, false); }
// Method to handle the Debugger DebuggerStop event. // The debugger will remain in debugger stop mode until this event // handler returns, at which time DebuggerStopEventArgs.ResumeAction should // be set to indicate how the debugger should proceed (Continue, StepInto, // StepOut, StepOver, Stop). // This handler should run a REPL (Read Evaluate Print Loop) to allow user // to investigate the state of script execution, by processing user commands // with the Debugger.ProcessCommand method. If a user command releases the // debugger then the DebuggerStopEventArgs.ResumeAction is set and this // handler returns. private void HandleDebuggerStopEvent(object sender, DebuggerStopEventArgs args) { Debugger debugger = sender as Debugger; DebuggerResumeAction? resumeAction = null; // Display messages pertaining to this debugger stop. WriteDebuggerStopMessages(args); // Simple REPL (Read Evaluate Print Loop) to process // Debugger commands. while (resumeAction == null) { // Write debug prompt. Console.Write("[DBG] PS >> "); string command = Console.ReadLine(); Console.WriteLine(); // Stream output from command processing to console. var output = new PSDataCollection<PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { Console.WriteLine(item); } }; // Process command. // The Debugger.ProcesCommand method will parse and handle debugger specific // commands such as 'h' (help), 'list', 'stepover', etc. If the command is // not specific to the debugger then it will be evaluated as a PowerShell // command or script. The returned DebuggerCommandResults object will indicate // whether the command was evaluated by the debugger and if the debugger should // be released with a specific resume action. PSCommand psCommand = new PSCommand(); psCommand.AddScript(command).AddCommand("Out-String").AddParameter("Stream", true); DebuggerCommandResults results = debugger.ProcessCommand(psCommand, output); if (results.ResumeAction != null) { resumeAction = results.ResumeAction; } } // Return from event handler with user resume action. args.ResumeAction = resumeAction.Value; }
/// <summary> /// Process debugger command. /// </summary> /// <param name="command">Debugger PSCommand</param> /// <param name="output">Output</param> /// <returns>DebuggerCommandResults</returns> public override DebuggerCommandResults ProcessCommand(PSCommand command, PSDataCollection<PSObject> output) { CheckForValidateState(); _detachCommand = false; if (command == null) { throw new PSArgumentNullException("command"); } if (output == null) { throw new PSArgumentNullException("output"); } if (!DebuggerStopped) { throw new PSInvalidOperationException( DebuggerStrings.CannotProcessDebuggerCommandNotStopped, null, Debugger.CannotProcessCommandNotStopped, ErrorCategory.InvalidOperation, null); } DebuggerCommandResults results = null; // Execute command on server. bool executionError = false; using (_psDebuggerCommand = GetNestedPowerShell()) { foreach (var cmd in command.Commands) { cmd.MergeMyResults(PipelineResultTypes.All, PipelineResultTypes.Output); _psDebuggerCommand.AddCommand(cmd); } PSDataCollection<PSObject> internalOutput = new PSDataCollection<PSObject>(); internalOutput.DataAdded += (sender, args) => { foreach (var item in internalOutput.ReadAll()) { if (item == null) { return; } DebuggerCommand dbgCmd = item.BaseObject as DebuggerCommand; if (dbgCmd != null) { bool executedByDebugger = (dbgCmd.ResumeAction != null || dbgCmd.ExecutedByDebugger); results = new DebuggerCommandResults(dbgCmd.ResumeAction, executedByDebugger); } else if (item.BaseObject is DebuggerCommandResults) { results = item.BaseObject as DebuggerCommandResults; } else { output.Add(item); } } }; try { _psDebuggerCommand.Invoke(null, internalOutput, null); } catch (Exception e) { CommandProcessor.CheckForSevereException(e); executionError = true; RemoteException re = e as RemoteException; if ((re != null) && (re.ErrorRecord != null)) { // Allow the IncompleteParseException to throw so that the console // can handle here strings and continued parsing. if (re.ErrorRecord.CategoryInfo.Reason == typeof(IncompleteParseException).Name) { throw new IncompleteParseException( (re.ErrorRecord.Exception != null) ? re.ErrorRecord.Exception.Message : null, re.ErrorRecord.FullyQualifiedErrorId); } // Allow the RemoteException and InvalidRunspacePoolStateException to propagate so that the host can // clean up the debug session. if ((re.ErrorRecord.CategoryInfo.Reason == typeof(InvalidRunspacePoolStateException).Name) || (re.ErrorRecord.CategoryInfo.Reason == typeof(RemoteException).Name)) { throw new PSRemotingTransportException( (re.ErrorRecord.Exception != null) ? re.ErrorRecord.Exception.Message : string.Empty); } } // Allow all PSRemotingTransportException and RemoteException errors to propagate as this // indicates a broken debug session. if ((e is PSRemotingTransportException) || (e is RemoteException)) { throw; } output.Add( new PSObject( new ErrorRecord( e, "DebuggerError", ErrorCategory.InvalidOperation, null))); } } executionError = executionError || _psDebuggerCommand.HadErrors; _psDebuggerCommand = null; // Special processing when the detach command is run. _detachCommand = (!executionError) && (command.Commands.Count > 0) && (command.Commands[0].CommandText.Equals("Detach", StringComparison.OrdinalIgnoreCase)); return results ?? new DebuggerCommandResults(null, false); }
private void DebuggerOnDebuggerStop(object sender, DebuggerStopEventArgs args) { Debugger debugger = sender as Debugger; DebuggerResumeAction?resumeAction = null; DebuggingInBreakpoint = true; try { if ( ((ScriptingHostUserInterface)host.UI).CheckSessionCanDoInteractiveAction( nameof(DebuggerOnDebuggerStop), false)) { var output = new PSDataCollection <PSObject>(); output.DataAdded += (dSender, dArgs) => { foreach (var item in output.ReadAll()) { host.UI.WriteLine(item.ToString()); } }; var message = Message.Parse(this, "ise:breakpointhit"); //var position = args.InvocationInfo.DisplayScriptPosition; IScriptExtent position; try { position = args.InvocationInfo.GetType() .GetProperty("ScriptPosition", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty) .GetValue(args.InvocationInfo) as IScriptExtent; } catch (Exception) { position = args.InvocationInfo.DisplayScriptPosition; } if (position != null) { message.Arguments.Add("Line", (position.StartLineNumber - 1).ToString()); message.Arguments.Add("Column", (position.StartColumnNumber - 1).ToString()); message.Arguments.Add("EndLine", (position.EndLineNumber - 1).ToString()); message.Arguments.Add("EndColumn", (position.EndColumnNumber - 1).ToString()); } else { message.Arguments.Add("Line", (args.InvocationInfo.ScriptLineNumber - 1).ToString()); message.Arguments.Add("Column", (args.InvocationInfo.OffsetInLine - 1).ToString()); message.Arguments.Add("EndLine", (args.InvocationInfo.ScriptLineNumber).ToString()); message.Arguments.Add("EndColumn", (0).ToString()); } message.Arguments.Add("HitCount", args.Breakpoints.Count > 0 ? args.Breakpoints[0].HitCount.ToString() : "1"); SendUiMessage(message); while (resumeAction == null && !abortRequested) { if (ImmediateCommand is string commandString) { PowerShellLog.Info($"Executing a debug command in ScriptSession '{Key}'."); PowerShellLog.Debug(commandString); DebuggerCommandResults results = null; try { var psCommand = new PSCommand(); var scriptCommand = new Command(commandString, true) { MergeUnclaimedPreviousCommandResults = PipelineResultTypes.Warning }; psCommand.AddCommand(scriptCommand) .AddCommand(OutDefaultCommand); results = debugger?.ProcessCommand(psCommand, output); ImmediateResults = output; LogErrors(null, output.ToList()); } catch (Exception ex) { PowerShellLog.Error("Error while executing Debugging command.", ex); ImmediateCommand = null; host.UI.WriteErrorLine(GetExceptionString(ex, ExceptionStringFormat.Default)); } if (results?.ResumeAction != null) { resumeAction = results.ResumeAction; } ImmediateCommand = null; } else { Thread.Sleep(20); } } args.ResumeAction = resumeAction ?? DebuggerResumeAction.Continue; } } finally { DebuggingInBreakpoint = false; } }
/// <summary> /// Create pipeline. /// </summary> internal Pipeline CreatePipeline(string line, bool addToHistory, bool useNestedPipelines) { // This method allows input commands to work against no-language runspaces. If a runspace // is pushed, it tries to parse the line using a ScriptBlock object. If a runspace is not // pushed, or if the parsing fails, in these cases it reverts to calling CreatePipeline // using the unparsed line. Pipeline pipeline = null; // In Start-PSSession scenario try to create a pipeline by parsing the line as a script block. if (this.IsRunspaceOverridden) { // Win8: exit should work to escape from the restrictive session if ((_runspaceRef.Value is RemoteRunspace) && (!string.IsNullOrEmpty(line) && string.Equals(line.Trim(), "exit", StringComparison.OrdinalIgnoreCase))) { line = "Exit-PSSession"; } PSCommand psCommand = ParsePsCommandUsingScriptBlock(line, null); if (psCommand != null) { pipeline = useNestedPipelines ? _runspaceRef.Value.CreateNestedPipeline(psCommand.Commands[0].CommandText, addToHistory) : _runspaceRef.Value.CreatePipeline(psCommand.Commands[0].CommandText, addToHistory); pipeline.Commands.Clear(); foreach (Command command in psCommand.Commands) { pipeline.Commands.Add(command); } } } // If that didn't work out fall-back to the traditional approach. if (pipeline is null) { pipeline = useNestedPipelines ? _runspaceRef.Value.CreateNestedPipeline(line, addToHistory) : _runspaceRef.Value.CreatePipeline(line, addToHistory); } // Add robust connection callback if this is a pushed runspace. RemotePipeline remotePipeline = pipeline as RemotePipeline; if (this.IsRunspaceOverridden && remotePipeline != null) { PowerShell shell = remotePipeline.PowerShell; if (shell.RemotePowerShell != null) { shell.RemotePowerShell.RCConnectionNotification += HandleRCConnectionNotification; } // Add callback to write robust connection errors from stream. shell.ErrorBuffer.DataAdded += (sender, eventArgs) => { RemoteRunspace remoteRunspace = _runspaceRef.Value as RemoteRunspace; PSDataCollection <ErrorRecord> erBuffer = sender as PSDataCollection <ErrorRecord>; if (remoteRunspace != null && erBuffer != null && remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.Host != null) { Collection <ErrorRecord> erRecords = erBuffer.ReadAll(); foreach (var er in erRecords) { remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.Host.UI.WriteErrorLine(er.ToString()); } } }; } pipeline.SetHistoryString(line); return(pipeline); }
/// <summary> /// Method to run the sample script and handle debugger events. /// </summary> public void Run() { Console.WriteLine("Starting PowerShell Debugger Sample"); Console.WriteLine(); // Create sample script file to debug. string fileName = "PowerShellSDKDebuggerSample.ps1"; string filePath = System.IO.Path.Combine(Environment.CurrentDirectory, fileName); System.IO.File.WriteAllText(filePath, _script); using (Runspace runspace = RunspaceFactory.CreateRunspace()) { // Open runspace and set debug mode to debug PowerShell scripts and // Workflow scripts. PowerShell script debugging is enabled by default, // Workflow debugging is opt-in. runspace.Open(); runspace.Debugger.SetDebugMode(DebugModes.LocalScript); using (PowerShell powerShell = PowerShell.Create()) { powerShell.Runspace = runspace; // Set breakpoint update event handler. The breakpoint update event is // raised whenever a break point is added, removed, enabled, or disabled. // This event is generally used to display current breakpoint information. runspace.Debugger.BreakpointUpdated += HandlerBreakpointUpdatedEvent; // Set debugger stop event handler. The debugger stop event is raised // whenever a breakpoint is hit, or for each script execution sequence point // when the debugger is in step mode. The debugger remains stopped at the // current execution location until the event handler returns. When the // event handler returns it should set the DebuggerStopEventArgs.ResumeAction // to indicate how the debugger should proceed: // - Continue Continue execution until next breakpoint is hit. // - StepInto Step into function. // - StepOut Step out of function. // - StepOver Step over function. // - Stop Stop debugging. runspace.Debugger.DebuggerStop += HandleDebuggerStopEvent; // Set initial breakpoint on line 10 of script. This breakpoint // will be in the script workflow function. powerShell.AddCommand("Set-PSBreakpoint").AddParameter("Script", filePath).AddParameter("Line", 10); powerShell.Invoke(); Console.WriteLine("Starting script file: " + filePath); Console.WriteLine(); // Run script file. powerShell.Commands.Clear(); powerShell.AddScript(filePath).AddCommand("Out-String").AddParameter("Stream", true); var scriptOutput = new PSDataCollection <PSObject>(); scriptOutput.DataAdded += (sender, args) => { // Stream script output to console. foreach (var item in scriptOutput.ReadAll()) { Console.WriteLine(item); } }; powerShell.Invoke <PSObject>(null, scriptOutput); } } // Delete the sample script file. if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } Console.WriteLine("PowerShell Debugger Sample Complete"); Console.WriteLine(); Console.WriteLine("Press any key to exit."); Console.ReadKey(true); }