using System.Collections.ObjectModel; using System.Globalization; using System.Management.Automation; using System.Management.Automation.Host; using System.Security; using System.Text; namespace PowershellHarness; // A whole bunch of empty implementations just so cmdlets have access to anything within Host.Ui (and probably any cmdlets // that prompt for information later) // https://github.com/leechristensen/OffensivePowerShellTasking/blob/master/OffensivePowerShellTasking/CustomPSHost.cs#L13 public class CustomHost : PSHost { public override string Name => "Custom Host"; public override Version Version { get; } = new Version(0, 0, 0, 0); public override Guid InstanceId { get; } = Guid.NewGuid(); private CustomUiHost _ui = new CustomUiHost(); public override CustomUiHost UI => _ui; public override CultureInfo CurrentCulture { get; } = CultureInfo.CurrentCulture; public override CultureInfo CurrentUICulture { get; } = CultureInfo.CurrentUICulture; public CustomHost(int width, int height = 100) { _ui.RawUI.WindowSize = new() { Width = width, Height = height }; } public override void EnterNestedPrompt() { throw new NotImplementedException("EnterNestedPrompt is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override void ExitNestedPrompt() { throw new NotImplementedException("ExitNestedPrompt is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override void NotifyBeginApplication() { } public override void NotifyEndApplication() { } public override void SetShouldExit(int exitCode) { } } // https://github.com/leechristensen/OffensivePowerShellTasking/blob/d1b498d874948f41e6dc053204c511fa6fc11c9c/OffensivePowerShellTasking/CustomPSHostUserInterface.cs#L8 public class CustomUiHost : PSHostUserInterface { // The only stuff that really matters to expose a host for any cmdlets private readonly CustomRawUiHost _rawUI = new CustomRawUiHost(); public override CustomRawUiHost RawUI => _rawUI; // Replace StringBuilder with whatever your preferred output method is (e.g. a socket or a named pipe) public StringBuilder output { get; set; } public CustomUiHost() { output = new StringBuilder(); } public CustomUiHost(ref StringBuilder sb) { output = sb; } public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value) { //output.Append("!").Append(value); } public override void WriteLine() { //output.Append("!").Append("\n"); } public override void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value) { //output.Append("!").Append(value + "\n"); } public override void Write(string value) { //output.Append("!").Append(value); } public override void WriteDebugLine(string message) { //output.Append("!").AppendLine("DEBUG: " + message); } public override void WriteErrorLine(string value) { //output.Append("!").AppendLine("ERROR: " + value); } public override void WriteLine(string value) { //output.Append("!").AppendLine(value); } public override void WriteVerboseLine(string message) { //output.Append("!").AppendLine("VERBOSE: " + message); } public override void WriteWarningLine(string message) { //output.Append("!").AppendLine("WARNING: " + message); } public override void WriteProgress(long sourceId, ProgressRecord record) { } public string Output => output.ToString(); public override Dictionary Prompt(string caption, string message, System.Collections.ObjectModel.Collection descriptions) { throw new NotImplementedException("Prompt is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override int PromptForChoice(string caption, string message, System.Collections.ObjectModel.Collection choices, int defaultChoice) { throw new NotImplementedException("PromptForChoice is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options) { throw new NotImplementedException("PromptForCredential1 is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName) { throw new NotImplementedException("PromptForCredential2 is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override string ReadLine() { throw new NotImplementedException("ReadLine is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override SecureString ReadLineAsSecureString() { throw new NotImplementedException("ReadLineAsSecureString is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } } // https://github.com/leechristensen/OffensivePowerShellTasking/blob/master/OffensivePowerShellTasking/CustomPSRHostRawUserInterface.cs#L8 public class CustomRawUiHost : PSHostRawUserInterface { public override ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black; public override Size BufferSize { get; set; } = new Size { Width = 100, Height = 1000 }; public override Coordinates CursorPosition { get; set; } = new Coordinates { X = 0, Y = 0 }; public override int CursorSize { get; set; } = 1; public override void FlushInputBuffer() { throw new NotImplementedException("FlushInputBuffer is not implemented."); } public override ConsoleColor ForegroundColor { get; set; } = ConsoleColor.White; public override BufferCell[,] GetBufferContents(Rectangle rectangle) { throw new NotImplementedException("GetBufferContents is not implemented."); } public override bool KeyAvailable { get { throw new NotImplementedException("KeyAvailable is not implemented."); } } public override Size MaxPhysicalWindowSize { get; } = new Size { Width = int.MaxValue, Height = int.MaxValue }; public override Size MaxWindowSize { get; } = new Size { Width = 100, Height = 100 }; public override KeyInfo ReadKey(ReadKeyOptions options) { throw new NotImplementedException("ReadKey is not implemented. The script is asking for input, which is a problem since there's no console. Make sure the script can execute without prompting the user for input."); } public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill) { throw new NotImplementedException("ScrollBufferContents is not implemented"); } public override void SetBufferContents(Rectangle rectangle, BufferCell fill) { throw new NotImplementedException("SetBufferContents is not implemented."); } public override void SetBufferContents(Coordinates origin, BufferCell[,] contents) { throw new NotImplementedException("SetBufferContents is not implemented"); } public override Coordinates WindowPosition { get; set; } = new Coordinates { X = 0, Y = 0 }; public override Size WindowSize { get; set; } = new Size { Width = 120, Height = 100 }; public override string WindowTitle { get; set; } = ""; }