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;
}
3
  • 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 property Commented Jan 30, 2020 at 14:36
  • And since Powershell 5.0, Write-Host is an alias for Write-Information. It shouldn't raise any errors. You're using an outdated Powershell version. The solution is to upgrade it to the current version Commented Jan 30, 2020 at 14:39
  • Thank you. I"m going to give it a try. Will let you know. Commented Jan 30, 2020 at 14:41

2 Answers 2

6

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
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

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());
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.