2017-01-09 30 views
0

私はLync/S4f/Exchangeサーバー上でリモートpowershellを実行しています。同期操作はすべて正常に動作しますが、私はロードブロックをヒットして非同期に変換しています。PowershellリモートパイプラインでのPipeline.AsyncInvoke

RunSpaceは標準のBeginOpen/EndOpenおよびBeginClose/EndClose操作を提供するため、非同期に接続/切断を行うことができましたが、InvokeAsyncはvoid型です。

ここに私のコードは、(connectionInfoが

new Uri("https://" + config.Server + "/ocspowershell") 

を次のようにURIを設定し、これは実際のリモート実行コード

Runspace myRunSpace = RunspaceFactory.CreateRunspace(connectionInfo); 
myRunSpace.Open(); 
using (Pipeline pipeLine = myRunSpace.CreatePipeline()) 
{ 
    Command myCommand = new Command("Get-CsArchivingPolicy"); 
    pipeLine.Commands.Add(myCommand); 
    pipeLine.StateChanged += PipeLine_StateChanged; 
    waiter = new TaskCompletionSource<Collection<PSObject>>(); 
    pipeLine.Error.DataReady += Error_DataReady; 
    pipeLine.Output.DataReady += Output_DataReady; 
    pipeLine.InvokeAsync(); 
    pipeLine.Input.Close(); 
    await waiter.Task.ConfigureAwait(false); 
} 

でいるWSManConnectionInfoは、ここで私が見てんだよます。.. た場合です私は入力を閉じないで、実行中のパイプライン以外に何も起こりません。

入力を閉じるとすぐにError_DataReady 0個のアイテムが読み込まれ、EndOfPipelineがtrueの場合、EndOfPipelineがtrue、Countも0になるため、Output_DataReadyが取得されます。

パイプラインがCompleted状態になります。コマンドは実行されますが、出力はどこにありますか?

私はpipeline.Invokeを行う場合、私は戻って私の結果と素晴らしいコレクションを得る..私はコマンドが正しいことを知っている。しかし、私は、非同期モードで実行しているときに、出力に関して何か不足しているはずです。

+0

Exchange 'pipeLine.Input.Close();'と 'pipeLine.InvokeAsync();'です。 – PetSerAl

+0

それは実行が行く限り、トリック..です。しかし、reder.Read(reader.Count = PipelineReaderのから、Output_DataReadyから取得したものは、メソッドがサポートされていないことを示す例外が常にスローされます(reader.ReadToEndと同様)。正しく理解することはできません結果を読む? – user3566056

答えて

0

私は、非同期処理を行う代わりの方法を見つけました。

  using (PowerShell ps = PowerShell.Create()) 
      { 
       if (remoteRunspacePool != null) 
        ps.RunspacePool = remoteRunspacePool; 
       else 
        ps.Runspace = remoteRunSpace; 
       Command myCommand = new Command(getPolicyExtractionCommand(dummy)); 
       Command myCommand2 = new Command("Select-Object"); 
       ps.Commands.AddCommand(myCommand); 
       var props = new string[] { "Identity", "Description", "Name" }; 
       myCommand2.Parameters.Add("Property", getPropertiesForPolicies(dummy)); 
       ps.Commands.AddCommand(myCommand2); 

       PSDataCollection<PSObject> execRes = await Task.Factory.FromAsync(beingRes, ps.EndInvoke).ConfigureAwait(false); 
       Collection<PSObject> processes = execRes.ReadAll(); 
      } 

PowerShellクラスを使用するのは、通常の古い非同期の非同期のInvokeのBeginメソッドとEndメソッドです。その後、TAPを使用して、これを現代のスタイルの非同期実行にラップすることができます。

前回のサンプルと同様に、以前に設定したランスペースがある場合は、PowerShellインスタンスに割り当てることができます。また、RunspacePool(IAsyncresultスタイルのOpenメソッドとCloseメソッドをサポートしています)で動作します。残念ながら、Runspace上のOpenAsyncとCloseAsyncは、状態変更を待つ必要があるこの奇妙な構造で作られています(StateChangedイベントを呼び出す、OpenAsyncを呼び出す、エラーを待つかステータスを開いてから実行を続ける)。

IMHO Microsoftは、PowerShellにもう少し非同期的な愛を示すべきです。