バックグラウンド
- Windows 7 で Powershell 2.0 を使用しています。
- Powershell モジュールでコマンドレットを作成しています (「モジュール」は Powershell 2.0 の新機能です)。
- コマンドレットをテストするために、Visual Studio 2008 でコマンドレットをプログラムで呼び出す単体テストを作成しています。
参照
- 「コマンドレット内からコマンドレットを呼び出す方法」というMSDN のこの記事には、C# からコマンドレットを呼び出す方法が示されています。
ソースコード
これは私の実際のコードの要約版です — 私が抱えている問題をはっきりと見ることができるように、コードをできるだけ小さくしました:
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 年 7 月 20 日の更新
これは、以下の回答に基づくソースコードです。
* 「Get-Colors」コマンドレットを呼び出す方法 (理想的には、文字列として 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");
}
}
}
上記のコードは、次の出力を生成します。
d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe
verbose output: 42
2010 年 1 月 16 日の更新
Powershell クラス (System.Management.Automation にありますが、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");
}
}