Repository: microsoft/CSS-Exchange
File: Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerEngineHandler.ps1 (PowerShell)

Code before:
            if ($null -ne $noResults) {
                Write-Verbose "Analyzer failed for the following servers: $([string]::Join(", ", $noResults))"
                $getJobQueue = Get-JobQueue
                foreach ($failedJobKey in $noResults) {
                    $serverName = $getJobQueue[$failedJobKey].JobParameter.ArgumentList.ServerName
                    Write-Verbose "Working on Server $serverName"
                    $singleServerStopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    $analyzedResults = Invoke-JobAnalyzerEngine -HealthServerObject $getJobQueue[$failedJobKey].JobParameter.ArgumentList
                    Write-Verbose "$serverName Analyzer Engine took $($singleServerStopWatch.Elapsed.TotalSeconds) seconds"
                    $finalResultsProcessed.Add($serverName, $analyzedResults.HCAnalyzedResults)
                }
            }
            Write-Verbose "All servers to complete analyzed results $($stopWatch.Elapsed.TotalSeconds) seconds"

            foreach ($key in $getJobQueueResult.Keys) {
                if ( $null -eq $getJobQueueResult[$key]) {
                    # Skip over jobs that are null out.
                    continue
                }
                $analyzedResults = $getJobQueueResult[$key].HCAnalyzedResults
                $serverName = $analyzedResults.HealthCheckerExchangeServer.ServerName
                $finalResultsProcessed.Add($serverName, $analyzedResults)
            }
        }
    }
    end {
        Write-Verbose "Completed $($MyInvocation.MyCommand) and took $($stopWatch.Elapsed.TotalSeconds) seconds"
        return $finalResultsProcessed
    }
}


Review comment (bug):
Might need to add in some `try` `catch` logic here to handle a double failure. 

Code after:
                    $progressAnalyzerParams.PercentComplete = ($analysisCounter++ / $ServerDataCollection.Count * 100)
                    Write-Progress @progressAnalyzerParams
                    $analyzedResults = Invoke-JobAnalyzerEngine -HealthServerObject $healthServerObject
                    Write-Verbose "$($healthServerObject.ServerName) Analyzer Engine took $($singleServerStopWatch.Elapsed.TotalSeconds) seconds"
                    $finalResultsProcessed.Add($healthServerObject.ServerName, $analyzedResults.HCAnalyzedResults)
                } catch {
                    Invoke-CatchActions
                    # Use Write-Error to bubble up the error to us.
                    Write-Error "Failed to process $($healthServerObject.ServerName) for analysis"
                }
            }
        } else {
            foreach ($healthServerObject in $ServerDataCollection) {
                $progressAnalyzerParams.Status = "Add job for Server $($healthServerObject.ServerName)"
                $progressAnalyzerParams.PercentComplete = ($analysisCounter++ / $ServerDataCollection.Count * 100)
                Write-Progress @progressAnalyzerParams
                Add-JobAnalyzerEngine -HealthServerObject $healthServerObject -ExecutingServer $healthServerObject.ServerName #TODO: Improve this logic
            }
            Wait-JobQueue -ProcessReceiveJobAction ${Function:Invoke-RemotePipelineLoggingLocal}
            $getJobQueueResult = Get-JobQueueResult
            Write-Verbose "Saving out the JobQueue"
            Add-DebugObject -ObjectKeyName "GetJobQueue-AfterDataCollection" -ObjectValueEntry ((Get-JobQueue).Clone())
            $noResults = $getJobQueueResult.Keys | Where-Object { $null -eq $getJobQueueResult[$_] }

            if ($null -ne $noResults) {
                Write-Verbose "Analyzer failed for the following servers: $([string]::Join(", ", $noResults))"
                $getJobQueue = Get-JobQueue
                foreach ($failedJobKey in $noResults) {
                    try {
                        $serverName = $getJobQueue[$failedJobKey].JobParameter.ArgumentList.ServerName
                        Write-Verbose "Working on Server $serverName"
                        $singleServerStopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                        $analyzedResults = Invoke-JobAnalyzerEngine -HealthServerObject $getJobQueue[$failedJobKey].JobParameter.ArgumentList
                        Write-Verbose "$serverName Analyzer Engine took $($singleServerStopWatch.Elapsed.TotalSeconds) seconds"
                        $finalResultsProcessed.Add($serverName, $analyzedResults.HCAnalyzedResults)
                    } catch {
                        Invoke-CatchActions
                        # Use Write-Error to bubble up the error to us.
                        Write-Error "Failed to process $serverName for analysis"
                    }
                }
            }
            Write-Verbose "All servers to complete analyzed results $($stopWatch.Elapsed.TotalSeconds) seconds"

            foreach ($key in $getJobQueueResult.Keys) {
                if ( $null -eq $getJobQueueResult[$key]) {
                    # Skip over jobs that are null out.
                    continue
                }
                $analyzedResults = $getJobQueueResult[$key].HCAnalyzedResults
                $serverName = $analyzedResults.HealthCheckerExchangeServer.ServerName