param ( [string]$ServerName = ".", [Parameter(Mandatory=$true)][string]$PipeName ) # Use named pipe as stdin/out $Source = @" using System; using System.IO; using System.IO.Pipes; using System.Threading.Tasks; public static class StdPipe { public static void RouteToPipe(string pipeServer, string pipeName) { var pipeClient = new NamedPipeClientStream(pipeServer, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous); pipeClient.Connect(); var pipeReader = new StreamReader(pipeClient, Console.OutputEncoding); var pipeWriter = new StreamWriter(pipeClient, Console.InputEncoding); var pipeBuffer = new char[512]; var stdBuffer = new char[512]; var tasks = new Task[2] { pipeReader.ReadAsync(pipeBuffer, 0, pipeBuffer.Length), ReadFromStdinAsync(stdBuffer, 0, stdBuffer.Length) }; while (true) { var doneIdx = Task.WaitAny(tasks); var bytesRead = tasks[doneIdx].Result; if (doneIdx == 0) {//Input from pipe if (bytesRead == 0) {// If the pipe has closed out on us, punk out break; } Console.Out.Write(pipeBuffer, 0, bytesRead); Console.Out.Flush(); tasks[doneIdx] = pipeReader.ReadAsync(pipeBuffer, 0, pipeBuffer.Length); } else {//Input from stdin pipeWriter.Write(stdBuffer, 0, bytesRead); pipeWriter.Flush(); tasks[doneIdx] = ReadFromStdinAsync(stdBuffer, 0, stdBuffer.Length); } } } private static Task ReadFromStdinAsync(char[] buffer, int offset, int len) { return Task.Run(() => { return Console.In.Read(buffer, offset, len); }); } } "@ Add-Type -TypeDefinition $Source -Language CSharp [StdPipe]::RouteToPipe($ServerName, $PipeName)