带有等待标志和 IOErrors 的 Powershell Get-Content

Powershell Get-Content with Wait flag and IOErrors

我有一个 PowerShell 脚本,它以“即发即弃”的方式生成 x 个其他 PowerShell 脚本。

为了跟踪我刚刚启动的所有脚本的进度,我创建了一个临时文件,我让它们以 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

是否有添加重试的简单方法或如何确保我的脚本在文件锁定后仍然存在?

正如@ChiliYago 指出的那样,我应该使用作业。这就是我现在所做的。我必须弄清楚如何从许多脚本中获取输出。

所以我确实将我所有的工作添加到一系列工作中,并像这样监控它们。请注意,如果您的脚本在您调用 Receive-Job 后有多个输出,您可能会收到多行。请务必使用作为作业执行的脚本中的 Write-Output

$jobs=@()
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."