0

I am trying to run this C# code:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello | Out-File -FilePath myfile.txt");
ps.Invoke();

myfile.txt should contain Hello but the file does not exist. How can i redirect powershell commands standard output (and errors) ?

Thanks

*** EDIT ***

I have understood the problem: The Invoke command is not a blocking-command. So when Invoke() has finished, my file.txt does not exist yet.

Is there a way to wait for powershelgl script ending ? Thanks

5
  • 1
    Have you try using ps.AddCommand instead of ps.AddScript ? Commented May 10, 2023 at 6:39
  • Does that answer your question ? stackoverflow.com/questions/11015157/… Commented May 10, 2023 at 6:47
  • 2
    I've run your code and it works fine for me (console app NET Framework 4.7). Where are you looking for the file? It should be created where your exe file is located. Also check if execution policy is set correctly (unrestricted). Commented May 10, 2023 at 7:08
  • In fact I need to wait script execution end. But how can I do that ? Thanks Commented May 10, 2023 at 13:13
  • Invoke blocks the thread already. Commented May 10, 2023 at 13:20

1 Answer 1

1

I have understood the problem: The Invoke command is not a blocking-command. So when Invoke() has finished, my file.txt does not exist yet.

You've misunderstood the problem, Invoke() is a synchronous method.

You haven't specified a location in which to operate (eg. cd C:\some\path\ in the PowerShell script), so PowerShell will use the working directory of the hosting process as it's default location. The file will be written to the directory from which you launched your application, or the root of your user profile if you launched the application from the shell in Windows.


If you want to consume the output in your C# application, iterate over the return value from Invoke() instead:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello");

foreach (var outputItem in ps.Invoke()) {
  if (ps.HadErrors) {
    Console.WriteLine("Errors encountered!")
    foreach (var errorRecord in ps.Streams.Error) {
      Console.WriteLine(errorRecord);
      Console.WriteLine(errorRecord.ScriptStackTrace);
    }
    break;
  }
  Console.WriteLine(outputItem.BaseObject); // this will print the string Hello
}
Sign up to request clarification or add additional context in comments.

9 Comments

It does not display anything. I have also tried a script which takes time to execute. Your foreach look ends before scripts ending. Is there a way to wait and test if script execution is finished ?
@Bob5421 most likely explanation is that an error is encountered - I've updated the sample code to show how you might inspect those
Thanks i have already tried and i see nothing. What output do you see ?
I was trying with Write-Host instead of Write-Output. With Write-Host I do not see any error and I do not see any hello message...
|

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.