简体   繁体   English

PowerShell通过C#控制台输出不同

[英]PowerShell via C# Console Output different

Fairly new to C#, not so new to PowerShell. 相当新的C#,对PowerShell来说并不新鲜。

I want to use C# to execute PowerShell code. 我想使用C#来执行PowerShell代码。 However the output of objects isn't in the same as running commands in a PowerShell window. 但是,对象的输出与在PowerShell窗口中运行命令的输出不同。 I get back the object's name rather than its data. 我找回了对象的名字而不是它的数据。 Here's what I'm trying: 这是我正在尝试的:

string script = @"
    get-process | ft
";

PowerShell powerShell = PowerShell.Create();

powerShell.AddScript(script);
var results = powerShell.Invoke();
foreach (var item in results)
{
    Console.WriteLine(item);
}

Returns: 返回:

Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData

However in a PowerShell command line window it returns a more formated table view: 但是,在PowerShell命令行窗口中,它返回更加格式化的表视图:

PS C:\\Dropbox\\PowerShell> ps | PS C:\\ Dropbox \\ PowerShell> ps | ft FT

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id SI ProcessName ------- ------ ----- ----- ----- ------ -- -- ----------- 131 12 1980 2572 85 0.45 13216 1 acrotray 处理NPM(K)PM(K)WS(K)VM(M)CPU(s)Id SI ProcessName ------- ------ ----- ----- --- - ------ - - ----------- 131 12 1980 2572 85 0.45 13216 1 acrotray

Really would like two things: 真的想要两件事:

  1. code that will produce the same output as the PowerShell command window 将生成与PowerShell命令窗口相同的输出的代码
  2. an explanation of what is going on so I can learn how to navigate it better 对正在发生的事情的解释,以便我可以学习如何更好地导航它

Thanks in advance! 提前致谢!

I figured it out, thanks to a code example on codeproject I figured out that the command "out-string" needs to be added to the end of all commands. 我想通了,感谢codeproject上的代码示例,我发现命令“out-string”需要添加到所有命令的末尾。 So the extra code to add is: 所以要添加的额外代码是:

ps.AddCommand("Out-String"); ps.AddCommand( “OUT-字符串”);

I wonder if the console is simply doing this or if there is more to it. 我想知道控制台是否只是这样做,或者是否还有更多。

PowerShell uses its own XML formatting document to return table style output in the console and ISE. PowerShell使用自己的XML格式文档在控制台和ISE中返回表样式输出。 Out-String is where this formatting comes into play in your case as it will preserve the formatting(you can use the '-Stream' switch with out string to return each line as it is executed). Out-String是这种格式在你的情况下发挥作用的地方,因为它将保留格式(你可以使用带有out字符串的'-Stream'开关在执行时返回每一行)。

It is possible to extract information from an object passed back to C# without using out-string; 可以从传递回C#的对象中提取信息而不使用out-string; however, in my experience if you are just displaying this information; 但是,根据我的经验,如果你只是显示这些信息; it is your best option to return a string. 这是返回字符串的最佳选择。 However, if you need to do additional processing on the object you can return an object and then perform conditionals based on what type of object you are dealing with. 但是,如果需要对对象执行其他处理,则可以返回一个对象,然后根据要处理的对象类型执行条件。 For example, if I need to manipulate objects once returned from PowerShell (not using 'out-string') I use the following: 例如,如果我需要操作从PowerShell返回的对象(不使用'out-string'),我使用以下内容:

System.Diagnostic.Process is your returned object type from the Get-Process Command - Make sure you know exactly what object type you are passing back to C# System.Diagnostic.Process是Get-Process命令中返回的对象类型 - 确保您确切知道要传递回C#的对象类型

using (PowerShell psRunspace = PowerShell.Create())
        {
            psRunspace.AddCommand("Get-Process");
            psRunspace.AddParameter("ComputerName", computerName);

            Collection<PSObject> outputObj = psRunspace.Invoke();

            foreach (PSObject obj in outputObj)
            {
                var objProperties = obj.Properties;
                var objMethods = obj.Methods;
                var baseObj = obj.BaseObject;

                if (baseObj is System.Diagnostic.Process) 
                {
                    var p = (System.Diagnostic.Process)baseObj;
                    //you can now access all members of this object normally
                    //Do something here with p.Properties or p.Methods etc...
                }
            }

I would also recommend, since I don't see it in your question, consider using a 'using' statement to execute your powershell command. 我也建议,因为我没有在你的问题中看到它,考虑使用'using'语句来执行你的powershell命令。 this will open and close the pipeline/runspace for you. 这将为您打开和关闭管道/运行空间。 In your example is doesn't seem like you closed that pipeline unless you just omitted it from your example code. 在您的示例中,似乎您没有关闭该管道,除非您从示例代码中省略它。 Also, be specific in your invoke command that you use the appropriate type for the objects you are returning and use a Collection as shown above with the type of objects you are returning (PSObject). 此外,在您的invoke命令中,您可以使用适合您要返回的对象的类型,并使用上面显示的Collection和您要返回的对象类型(PSObject)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM