Как получить подробный вывод Powershell CmdLet, когда CmdLet программно вызывается из C #

BACKGROUND I am using Powershell 2.0 on Windows 7. I am writing a cmdlet in a Powershell module ("module" is new to Powershell 2.0). To test the cmdlet I am writing Unit tests in Visual Studio 2008 that programmatically invoke the cmdlet. REFERENCE This Article on MSDN called "How to Invoke a Cmdlet from Within a Cmdlet" shows how to call a cmdlet from C#. THE SOURCE CODE

This is a distilled version of my actual code — I've made it as small as possible so that you can see the problem I am having clearly:

using System;
using System.Management.Automation;   

namespace DemoCmdLet1
{
    class Program
    {
        static void Main(string[] args)
        {
            var cmd = new GetColorsCommand();

                foreach ( var i in cmd.Invoke<string>())
                {
                   Console.WriteLine("- " + i );   
                } 
           } 
       } 

    [Cmdlet("Get", "Colors")]
    public class GetColorsCommand : Cmdlet
    {
        protected override void ProcessRecord()
        {
            this.WriteObject("Hello");
            this.WriteVerbose("World");
        }

    }
}
COMMENTS I understand how to enable and capture verbose output from the Powershell command line; that's not the problem. In this case I am programmatically invoking the cmdlet from C#. Nothing I've found addresses my specific scenario. Some articles suggest I should implement my own PSHost, but seems expensive and also it seems like a have to call the cmdlet as text, which I would like to avoid because that is not as strongly typed. UPDATE ON 2009-07-20

Вот исходный код, основанный на ответе ниже.

Некоторые вещи до сих пор мне не ясны: * Как вызывать & quot; Get-Colors & quot; командлет (в идеале, без необходимости передавать его как строку в объект ps) * Как получить подробный выводas it is generated вместо того, чтобы получить их коллекцию в конце.

    using System;
    using System.Management.Automation;   

    namespace DemoCmdLet1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var ps = System.Management.Automation.PowerShell.Create();

                ps.Commands.AddScript("$verbosepreference='continue'; write-verbose 42");

                foreach ( var i in ps.Invoke<string>())
                {
                   Console.WriteLine("normal output: {0}" , i );   
                }
                foreach (var i in ps.Streams.Verbose)
                {
                    Console.WriteLine("verbose output: {0}" , i);
                }

            }
        }

        [Cmdlet("Get", "Colors")]
        public class GetColorsCommand : Cmdlet
        {
            protected override void ProcessRecord()
            {
                this.WriteObject("Red");
                this.WriteVerbose("r");
                this.WriteObject("Green");
                this.WriteVerbose("g");
                this.WriteObject("Blue");
                this.WriteVerbose("b");

            }

        }
    }

Код выше генерирует этот вывод:

d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe
verbose output: 42
UPDATE ON 2010-01-16

с помощью класса Powershell (находится в System.Management.Automation, но только в версии сборки, которая поставляется с SDK powershell 2.0, а не в стандартной версии Windows 7), я могу программно вызвать командлет и получить подробный вывод. Оставшаяся часть заключается в том, чтобы фактически добавить пользовательский командлет к этому экземпляру PowerShell - потому что это было моей первоначальной целью - провести модульное тестирование моих командлетов, а не тех, которые поставляются с PowerShell.

class Program
{
    static void Main(string[] args)
    {
        var ps = System.Management.Automation.PowerShell.Create();
        ps.AddCommand("Get-Process");
        ps.AddParameter("Verbose");
        ps.Streams.Verbose.DataAdded += Verbose_DataAdded;
        foreach (PSObject result in ps.Invoke())
        {
            Console.WriteLine(
                    "output: {0,-24}{1}",
                    result.Members["ProcessName"].Value,
                    result.Members["Id"].Value);
        } 
        Console.ReadKey();
    }

    static void Verbose_DataAdded(object sender, DataAddedEventArgs e)
    {
        Console.WriteLine( "verbose output: {0}", e.Index);
    }
}


[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
    protected override void ProcessRecord()
    {
        this.WriteObject("Hello");
        this.WriteVerbose("World");
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос