none
PS3.0上でのManagement.Automation.PowerShellでのstreams.error.add_dataaddedについて RRS feed

  • 質問

  • いつも参考にさせていただいております。

    PowerShell+プログラマー初心者です。※元々基盤構築エンジニアで、最近まともな運用スクリプトを一式構築した程度

    外部PSスクリプトの実行をRunspace上で行いError、Waning等のイベントを検知した際に標準出力されたエラーを変数に格納して、

    ログファイルに”加工”して書き込むというようなスクリプトを作成しております。

    PS2.0では正常に動作していたスクリプトが3.0でハングしてしまう問題が生じており、

    デバッグした結果は以下のサイトのメソッドを使用する箇所でハングしているところまで確認できました。

    http://msdn.microsoft.com/en-us/library/dd182208(v=vs.85).aspx

    それ以上の追い方もわかりません。

    特に不明コマンドエラーが表示されるわけでもなく、PowerGUIでも候補に表示されるので利用できないことはないのかと思ってますがどなたかご教授いただけないでしょうか。

    作成したソースは以下です。

    try {
            $refData = ""
            $initialSessionState = [Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
            $initialSessionState.ThrowOnRunspaceOpenError = $true

            # 各ポリシーの設定
            $initialSessionState.Variables.Add( ( New-Object Management.Automation.Runspaces.SessionStateVariableEntry( 'VerbosePreference', continue, $null ) ) )
            $initialSessionState.Variables.Add( ( New-Object Management.Automation.Runspaces.SessionStateVariableEntry( 'DebugPreference', continue, $null ) ) )
            $initialSessionState.Variables.Add( ( New-Object Management.Automation.Runspaces.SessionStateVariableEntry( 'WarningPreference', continue, $null ) ) )
            $initialSessionState.Variables.Add( ( New-Object Management.Automation.Runspaces.SessionStateVariableEntry( 'ErrorActionPreference', continue, $null ) ) )

            $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace( $initialSessionState )
            $runspace.Open() | Out-Null
            
            $powershell = [Management.Automation.PowerShell]::Create()
            $powershell.Runspace = $runspace



    $powershell.Streams.Error.add_DataAdded( {
    $record = $powershell.Streams.Error[$_.Index]
    Write-ErrorLog -ErrorRecord $record
            } )| Out-Null
            $powershell.Streams.Warning.add_DataAdded( {
      $record = $powershell.Streams.Warning[$_.Index]
    Write-NormalLog $record.ToString() -EventType $CENV_MESSAGE_LEVEL_WARNING
            } )#| Out-Null
    $powershell.Streams.Verbose.add_DataAdded( {
    $record = $powershell.Streams.Verbose[$_.Index]
    Write-NormalLog $record.ToString()
            } )| Out-Null
            $powershell.Streams.Debug.add_DataAdded( {
                $record = $powershell.Streams.Debug[$_.Index]
                Write-NormalLog $record.ToString()
            } )| Out-Null

            $powershell.AddScript( $CommandLine )| Out-Null
            $powershell.Invoke()| Out-Null
            
            # Error.Countが1つでも検出でエラーとする
            if ( $powershell.Streams.Error.Count -gt 0 ) {
                Write-ErrorLog -Message "サブスクリプト '$scriptFileName' が異常終了しました。"
                return
            } elseif ( $powershell.Streams.Warning.Count -gt 0 ) {
                Write-NormalLog -Message "サブスクリプト '$scriptFileName' が警告終了しました。"
                return
            }
        } finally {
            if ( $runspace ){
                $runspace.Dispose() | Out-Null
            }
        }
        Write-NormalLog "サブスクリプト '$scriptFileName' が正常終了しました。"
        return $TRUE


    何卒宜しくお願いいたします。


    2013年12月13日 12:46

すべての返信

  • 原因については当方にも不明ですが、add_イベントハンドラではなく、Register-ObjectEventコマンドレットを用いた.NETオブジェクトのイベント購読を行った場合はどうでしょうか?

    2013年12月14日 0:40
    モデレータ
  • ご回答ありがとうございます。

    代用できそう情報として理解したのですが、

    get-help Register-ObjectEvent -fullの内容が今一理解できなかったので、

    少しお勉強してから実行してみます。

    少しお時間いただけますか。

    宜しくお願いいたします。


    2013年12月14日 12:07