2

When running the script in Powershell i'm able to receive the Write-Host output but not in C#.
Here is the code for the output Write-Host "HELLO WORLD TEST."
The application fails when it reaches this line:
Collection<PSObject> results = pipeline.Invoke();
I receive this error message:

HostException: A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows

How can I return the output of Write-Host? Thanks in advance.

protected void Page_Load(object sender, EventArgs e) {

    if (!IsPostBack) {
        RunScript(@"C:\TestScript.ps1");
    }
}

private string RunScript(string scriptText) {

    Runspace runspace = RunspaceFactory.CreateRunspace();

    runspace.Open();

    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(scriptText);

    pipeline.Commands.Add("Out-String");

    Collection < PSObject > results = pipeline.Invoke();

    runspace.Close();

    StringBuilder stringBuilder = new StringBuilder();
    foreach(PSObject obj in results) {
        //do something
    }
    return Textbox.Text;
}
Riccardo
  • 1,083
  • 2
  • 15
  • 25
Tom
  • 79
  • 1
  • 10
  • 1
    You don't need to create a RunSpace and pipelines. Since Powershell 2.0, you can use `Powershell.Create`. All output streams are available through the [Powershell.Streams](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.powershell.streams?view=powershellsdk-1.1.0) property – Panagiotis Kanavos Jan 30 '20 at 14:36
  • And since Powershell 5.0, [`Write-Host` is an alias for `Write-Information`](https://learn.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Write-Host?view=powershell-5.1#description). It shouldn't raise any errors. You're using an outdated Powershell version. The solution is to upgrade it to the current version – Panagiotis Kanavos Jan 30 '20 at 14:39
  • Thank you. I"m going to give it a try. Will let you know. – Tom Jan 30 '20 at 14:41

2 Answers2

4

You can work with PowerShell like this. Create an instance and add listeners for all the Powershell streams that are of interest to you:

private string RunScript(string scriptText)
{


    System.Management.Automation.PowerShell powerShellInstance = System.Management.Automation.PowerShell.Create();

powerShellInstance.Streams.Information.DataAdded += InformationHandler;

    powerShellInstance.Streams.Verbose.DataAdded += InformationalRecordEventHandler<VerboseRecord>;

    powerShellInstance.Streams.Debug.DataAdded += InformationalRecordEventHandler<DebugRecord>;

    powerShellInstance.Streams.Warning.DataAdded += InformationalRecordEventHandler<WarningRecord>;

    powerShellInstance.AddScript(scriptText);
                        powerShellInstance.Invoke();               
}

 static void InformationalRecordEventHandler<T>(object sender, DataAddedEventArgs e) 
        where T : InformationalRecord
    {
        var newRecord = ((PSDataCollection<T>)sender)[e.Index];
        if (!string.IsNullOrEmpty(newRecord.Message))
        {
            //STORE your message somewhere
        }
    }

static void InformationHandler(object sender, DataAddedEventArgs e)
    {
        var newRecord = ((PSDataCollection<InformationRecord>)sender)[e.Index];
        if (newRecord?.MessageData != null)
        {
            //STORE your message somewhere
        }
    }
vhr
  • 1,528
  • 1
  • 13
  • 21
0

If you want to keep using the Pipeline class, you can use the Command.MergeMyResults method. For example, to redirect all type of streams to pipeline output:

private string RunScript(string scriptText) {

    Runspace runspace = RunspaceFactory.CreateRunspace();

    runspace.Open();

    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript("Write-Host Test");
    pipeline.Commands[pipeline.Commands.Count-1]
       .MergeMyResults(PipelineResultTypes.All, PipelineResultTypes.Output)
    
    Collection < PSObject > results = pipeline.Invoke();

    runspace.Close();

    foreach(PSObject obj in results) {
        Console.WriteLine(obj.ToString());
    }
}
CravateRouge
  • 130
  • 7