async void Exception_Click(object sender, RoutedEventArgs e) { var files = await PoshConsole.InvokeAsync("throw 'whatever'"); if (files.State == PipelineState.Failed) { Dispatcher.Invoke(() => MainContent.DataContext = "Failed Command"); } }
private void Invoke_Click(object sender, RoutedEventArgs e) { if (CommandInput.Text.Length > 0) { // Oh man, please don't do anything like this with user inputs in the real world ... // But if you do, at least have the sense to make sure that isScript:false PoshConsole.InvokeAsync(Command.Text, isScript: false, input: CommandInput.Text.Split(' ')); } }
async void Input_Click(object sender, RoutedEventArgs e) { // this is not part of the test/demo ... we just need something to use as input // You should _not_ do this in lieu of using the pipeline var processes = await PoshConsole.InvokeAsync("Get-Process | Sort CPU -Descending | Select -First 10", output : ConsoleOutput.None); // Now invoke a command with pipeline input: await PoshConsole.InvokeAsync("Format-Table", isScript : false, input : processes.Output); Dispatcher.Invoke(() => MainContent.DataContext = processes.Output); }
async void Error_Click(object sender, RoutedEventArgs e) { var files = await PoshConsole.InvokeAsync("Get-ChildItem NoSuchFile"); if (files.State == PipelineState.Failed) { Dispatcher.Invoke(() => MainContent.DataContext = "Failed Command"); } else if (!files.HadErrors) { Dispatcher.Invoke(() => MainContent.DataContext = files.Output); } }
async void Pipeline_Click(object sender, RoutedEventArgs e) { // When you want to accept user input for parameters, you should always build your pipeline using Commands var ps = new Command("Get-Process"); var sort = new Command("Sort-Object"); // That way, you can pass the user input to a specific parameter, and avoid code injection: sort.Parameters.Add("Property", ProcessSort.SelectedValue); // Switch parameters... if (ProcessDescending.IsChecked == true) { sort.Parameters.Add("Descending"); } // Note that PowerShell is still dynamic, so there's no validation going on here // But these parameter values are not script, so the user can't use $(tricks) to execute code var select = new Command("Select-Object"); select.Parameters.Add("First", (int)ProcessCount.Value); // Now pass them in order to InvokeAsync: var processes = await PoshConsole.InvokeAsync(new [] { ps, sort, select }); }
async void Secret_Click(object sender, RoutedEventArgs e) { var processes = await PoshConsole.InvokeAsync("Get-Process | Select -First 25", output : ConsoleOutput.None); Dispatcher.Invoke(() => MainContent.DataContext = processes.Output); }
/* * private void Console_PromptForObject(object sender, PromptForObjectEventArgs e) * { * * var results = new Dictionary<string, PSObject>(); * foreach (var fieldDescription in e.Descriptions) * { * var type = Type.GetType(fieldDescription.ParameterAssemblyFullName); * var prompt = string.IsNullOrEmpty(fieldDescription.Label) ? fieldDescription.Name : fieldDescription.Label; * if (type != null && type.IsArray) * { * type = type.GetElementType(); * var output = new List<PSObject>(); * int count = 0; * do * { * var single = GetSingle(e.Caption, e.Message, $"{prompt}[{count++}]", fieldDescription.HelpMessage, fieldDescription.DefaultValue, type); * if (single == null) break; * * if (!(single.BaseObject is string) || ((string)single.BaseObject).Length > 0) * { * output.Add(single); * } * else break; * } while (true); * * results[fieldDescription.Name] = PSObject.AsPSObject(output.ToArray()); * } * else * { * results[fieldDescription.Name] = GetSingle(e.Caption, e.Message, prompt, fieldDescription.HelpMessage, fieldDescription.DefaultValue, type); * } * * } * e.Results = results; * } * * private PSObject GetSingle(string caption, string message, string prompt, string help, PSObject psDefault, Type type) * { * if (null != type && type == typeof(PSCredential)) * { * return PSObject.AsPSObject(CredentialUI.Prompt(caption, message)); * } * * while (true) * { * // TODO: Only show the help message if they type '?' as their entry something, in which case show help and re-prompt. * if (!String.IsNullOrEmpty(help)) * Write(help + "\n"); * * Write($"{prompt}: "); * * if (null != type && typeof(SecureString) == type) * { * var userData = ReadLineAsSecureString() ?? new SecureString(); * return PSObject.AsPSObject(userData); * } // Note: This doesn't look the way it does in PowerShell, but it should work :) * else * { * if (psDefault != null && psDefault.ToString().Length > 0) * { * if (Dispatcher.CheckAccess()) * { * CurrentCommand = psDefault.ToString(); * _commandBox.SelectAll(); * } * else * { * Dispatcher.BeginInvoke(DispatcherPriority.Input, (Action<string>)(def => * { * CurrentCommand = def; * _commandBox.SelectAll(); * }), psDefault.ToString()); * } * } * * var userData = ReadLine(); * * if (type != null && userData.Length > 0) * { * object output; * var ice = TryConvertTo(type, userData, out output); * // Special exceptions that happen when casting to numbers and such ... * if (ice == null) * { * return PSObject.AsPSObject(output); * } * if ((ice.InnerException is FormatException) || (ice.InnerException is OverflowException)) * { * Write(ConsoleBrushes.ErrorForeground, ConsoleBrushes.ErrorBackground, * $@"Cannot recognize ""{userData}"" as a {type.FullName} due to a format error.\n"); * } * else * { * return PSObject.AsPSObject(String.Empty); * } * } * else if (userData.Length == 0) * { * return PSObject.AsPSObject(String.Empty); * } * else return PSObject.AsPSObject(userData); * } * } * } */ async void Capture_Click(object sender, RoutedEventArgs e) { var files = await PoshConsole.InvokeAsync(new Command("Get-ChildItem")); Dispatcher.Invoke(() => MainContent.DataContext = files.Output); }