我有一个PowerShell脚本,它以Fire-And-Forget方式生成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
是否有一种简单的方法可以添加重试,或者如何确保我的脚本能够保存文件锁?
答案 0 :(得分:0)
@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."