2009-07-18 9 views
8

背景

  • 私はPowerShellのモジュール内のコマンドレットを書いています
  • のWindows 7上のPowershell 2.0を使用しています(「モジュールから呼び出されたときにPowerShellのコマンドレットの詳細な出力をキャプチャする方法"Powershell 2.0の新機能です)。
  • コマンドレットをテストするために、Visual Studio 2008でプログラムによってコマンドレットを呼び出すUnitテストを作成しています。 「どのようにコマンドレットの中からコマンドレットを呼び出すために」と呼ばれる

REFERENCE

これは私の実際のコードの蒸留バージョンである

  • ソースコードは—私はそれをできるだけ小さくしました

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

コメント

  • Powershellコマンドラインから詳細な出力を有効にしてキャプチャする方法を理解しています。それは問題ではありません。
  • この場合、プログラムでC#からコマンドレットを呼び出しています。
  • 特定のシナリオに対応したものはありません。いくつかの記事では、私自身のPSHostを実装すべきだと示唆していますが、コストがかかると思われます。また、コマンドレットをテキストとして呼び出す必要があるようですが、強く型付けされていないため避けたいです。

ここで2009-07-20

ON UPDATEは、以下の回答に基づいてソースコードです。

いくつかのものはまだ私に明確ではありません。 *(理想的にPSのオブジェに文字列として渡しすることなく) 「をゲット-色」コマンドレットを呼び出すためにどのように*として冗長出力を取得する方法最後にそれらのコレクションを取得する代わりに、が生成されます。

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"); 

      } 

     } 
    } 

上記のコードは、この出力を生成する:System.Management.Automationにだけバージョンで見つかったPowershellのクラスを使用して2010-01-16

ON

d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe 
verbose output: 42 

UPDATE( PowerShell 2.0 SDKに付属しているアセンブリのうち、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"); 
    } 
} 

+1

私の答えでは欠落したバックティックがありました。これは、$ verbosepreference変数が事前に評価されるのを防ぎます。 – x0n

+0

あなたは私の回答を回答としてマークしていないのはなぜですか? – x0n

+0

リアルタイムの詳細なレコードが必要な場合は、powershellインスタンスのstreamsプロパティでdatachangedイベントにサブスクライブします。 – x0n

答えて

10
  • 冗長出力$VerbosePreferenceが、少なくともするように設定されていない限り、実際に出力されません「続行。」
  • あなたcmdletを実行するためのPowerShellタイプを使用して、PowerShellのスクリプトでStreams.Verbose propery

例からVerboseRecordインスタンスをお読みください。

ps> $ps = [powershell]::create() 
ps> $ps.Commands.AddScript("`$verbosepreference='continue'; write-verbose 42") 
ps> $ps.invoke() 
ps> $ps.streams.verbose 
Message InvocationInfo       PipelineIterationInfo 
------- --------------       --------------------- 
42  System.Management.Automation.Invocat... {0, 0} 

これは、C#に変換するのは簡単でなければなりません。

0
1.  string scriptFile = "Test.ps1"; 
2.  using (PowerShell ps = PowerShell.Create()) 
3.  { 
4.   const string getverbose = "$verbosepreference='continue'"; 
5.   ps.AddScript(string.Format(getverbose)); 
6.   ps.Invoke(); 
7.   ps.Commands.Clear(); 
8.   ps.AddScript(@".\" + scriptFile); 
9.   ps.Invoke(); 
10.   foreach (var v in ps.Streams.Verbose) 
11.   { 
12.    Console.WriteLine(v.Message); 
13.   } 
14.  } 

重要な行は5行目と6行目です。これは基本的にセッションと新しいコマンドとスクリプトの$ verbosepreferenceを設定します。