Search code examples
c#powershelloutputrunspace

How to catch full invoke text from powershell class in C#


I want to catch the output exactly as I get it when I run commands in PowerShell.

For instance when I type LS, I get:

enter image description here

Yet when I use this code:

        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();

        PowerShell ps = PowerShell.Create(); // Create a new PowerShell instance
        ps.Runspace = runspace; // Add the instance to the runspace
        ps.Commands.AddScript("ls"); // Add a script

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

        runspace.Close();


        StringBuilder stringBuilder = new StringBuilder();
        foreach (PSObject obj in results)
        {
            Console.WriteLine(obj.ToString());
        }

I get the following output:

Microsoft.Management.Infrastructure.dll
System.Management.Automation.dll
System.Management.Automation.xml
WpfApp1.exe
WpfApp1.exe.config
WpfApp1.pdb

Although this output may come in handy, with an other application I dont get the right output in return, so I would prefer the exact output as I see it in PowerShell itself.

Is there a way to read the output as I get it in PowerShell, line for line?


Solution

  • If you want the exact text that powershell produces you then you can use Out-String in the powershell command:

    ps.Commands.AddScript("ls | Out-String");
    

    enter image description here


    You can also read the values by accessing the Properties of the PSObject:

    foreach (PSObject obj in results)
    {
        var name = obj.Properties["Name"]?.Value.ToString()
        var mode = obj.Properties["Mode"]?.Value.ToString();
        var length = obj.Properties["Length"]?.Value.ToString();
        var lastMod = (DateTime?)obj.Properties["LastWriteTime"]?.Value;
    
        Console.WriteLine(string.Format("{0} {1} {2} {3}", mode, lastMod, length, name));
    }
    

    Note, as mentioned in mklement0's answer, you don't need to use Runspace to execute this powershell. Consider using Get-ChildItem rather than ls.