2017-10-05 6 views
0

PowerShellスクリプトには、x個の他のPowerShellスクリプトがFire-And-Forgetの方法で生成されています。WaitフラグとIOErrorsを使用したPowerShell Get-Content

開始するすべてのスクリプトの進行状況を追跡するために、一時ファイルを作成します。ここで、すべてのログメッセージをjson形式で書き込んで進捗状況を報告します。

親スクリプトでは、Get-Content -Waitを使用してログファイルを監視しています。ログファイルに行があるたびにjsonを解析し、Format-Tableを使って表示するオブジェクトの配列を更新します。こうすることで、さまざまなスクリプトがどのくらいプロセスにあるか、特定のステップで失敗するかどうかを確認できます。それはうまくいく...ほとんど。

非常に多くのスクリプトがログファイルにアクセスしているので、私はIOErrorsを使い続けています。そのときにスクリプトが異常終了し、何が起こっているのかに関するすべての情報が失われます。

IOErrorに実行されている生成されたスクリプトと一緒に暮らすことができます。なぜなら、それらはただ続行してから次のメッセージを捕まえるだけだからです。これは監査ログではなく、進捗ログであるため、一部のメッセージが失われて生きています。

しかし、ログの末尾にあるスクリプトがクラッシュすると、洞察力が失われます。

私はTry/Catchでこれをラップしようとしましたが、それは役に立ちません。私は試して/キャッチ内に-ErrorAction Stopを設定しようとしましたが、それでもエラーをキャッチしません。読み込み

私のスクリプトは次のようになります。

function WatchLogFile($statusFile) 
{ 
    Write-Host "Tailing statusfile: $($statusFile)" 
    Write-Host "Press CTRL-C to end." 
    Write-Host "" 
    Try { 
    Get-Content $statusFile -Force -Wait | 
     ForEach { 
      $logMsg = $_ | ConvertFrom-JSON 
      #Update status on step for specific service 
      $svc = $services | Where-Object {$_.Service -eq $logMsg.Service} 
      $svc.psobject.properties[$logMsg.step].value = $logMsg.status 

      Clear-Host 
      $services | Format-Table -Property Service,Old,New,CleanRepo,NuGet,Analyzers,CleanImports,Build,Invoke,Done,LastFailure 
     } -ErrorAction Stop 
    } Catch { 
     WatchLogFile $statusFile 
    } 
} 

と更新が生み出されたスクリプト

Add-Content $statusFile $jsonLogMessage 

にこのように書かれている再試行を追加する簡単な方法はありますかどのように私は確認することができます私のスクリプトはファイルのロックを引き継ぎますか?

+1

なぜジョブを使用していませんか? – ChiliYago

+0

私は知らない...なぜ私は仕事をしていないのですか?このスクリプトは、サーバー上ではなくデスクトップ上で実行されています。以前はPowerShellジョブを使用していませんでしたので、これを行う方法である可能性は認識していませんでした。この点で私が見なければならないJobsについて特に何かありますか? –

+0

それは私があなたを助けると思うトピックです。タイプ:PS:> help about_jobs – ChiliYago

答えて

0

@ChiliYagoが指摘するように、私は仕事を使うべきです。それが今私がやったことです。私は、それが多くのスクリプトから到着したときに出力を得る方法を理解しなければなりませんでした。

私は自分のすべてのジョブを一連のジョブに追加し、このように監視しました。 Receive-Jobを呼び出してからスクリプトに複数の出力がある場合は、複数の行を受け取ることができることに注意してください。ジョブとして実行するスクリプトにはWrite-Outputを必ず使用してください。

[email protected]() 
foreach ($script in $scripts) 
{ 
    $sb = [scriptblock]::create("$script $(&{$args} @jobArgs)") 
    $jobs += Start-Job -ScriptBlock $sb 
} 

while ($hasRunningJobs -gt 0) 
{ 
    $runningJobs = $jobs | Where-Object {$_.State -eq "Running"} | measure 
    $hasRunningJobs = $runningJobs.Count 

    foreach ($job in $jobs) 
    { 
     $outvar = Receive-Job -Job $job 
     if ($outvar) 
     { 
      $outvar -split "`n" | %{ UpdateStatusTable $_} 
     } 
    } 
} 

Write-Host "All scripts done." 
関連する問題