2017-10-05 41 views
0

我有一个PowerShell脚本,它以Fire-and-Forget方式生成x个其他PowerShell脚本。带有等待标志和IOErrors的Powershell Get-Content

为了跟踪我刚刚开始的所有脚本的进度,我创建了一个临时文件,其中我全部使用json格式编写日志消息来报告进度。

在父脚本中,我使用Get-Content -Wait监视该日志文件。每当我在日志文件中收到一行时,我都会解析json并更新一个对象数组,然后使用Format-Table显示。这样,我可以看到不同的脚本在他们的过程中有多远,以及它们是否在特定步骤失败。这很有效......差不多。

我一直在遇到IOErrors,因为有太多的脚本正在访问日志文件,当发生这种情况时,脚本只是中止,我失去了所发生的所有信息。

我将能够与生成的IOError运行的脚本生活在一起,因为他们只是继续,然后我只是捕获下一条消息。我可以忍受一些丢失的消息,因为这不是审计日志,而只是一个进度日志。

但是,当尾随日志的脚本崩溃时,我失去了洞察力。

我试图把这个包装在Try/Catch中,但这并没有帮助。我尝试在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作业,所以没有意识到可能是这样做的一种方式。乔布斯有什么特别的,我应该在这方面看? –

+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."