Private/Progress.ps1
|
# Progress on the Technician's console. # # Several Checks take seconds to minutes - the CPU sampled at rest, pings to every Server, # the disk write test, the stress test, the wait for the admin prompt - and a console that # prints a heading and then says nothing for a minute looks hung. So a Run shows one bar # for the Run and one beneath it for the Check that is waiting. # # Only Gatherers and the Run draw progress. A Judge touches nothing but its data, and the # Elevated Part silences progress altogether (Invoke-GutcheckElevated.ps1), because its # window is not the one the Technician watches. $script:ProgressRunId = 1 $script:ProgressCheckId = 2 # What the Check's bar last showed, so an unchanged bar is not drawn again: Write-Progress # is slow on Windows PowerShell 5.1, and the disk test reports from a loop of thousands. $script:ProgressLastShown = $null function Get-ProgressPercent { <# .SYNOPSIS How far along step Step of Of is, as a whole percentage from 0 to 100. Pure. #> [CmdletBinding()] [OutputType([int])] param([double]$Step, [double]$Of) if ($Of -le 0 -or $Step -le 0) { return 0 } [int][math]::Min(100, [math]::Floor($Step / $Of * 100)) } function Write-RunProgress { <# .SYNOPSIS The Run's own bar: which Check, and how many there are. #> [CmdletBinding()] [OutputType([void])] param( [Parameter(Mandatory)][int]$Index, [Parameter(Mandatory)][int]$Count, [Parameter(Mandatory)][string]$Name ) Complete-CheckProgress Write-Progress -Id $script:ProgressRunId -Activity (Get-Text 'Console.Progress.Activity') ` -Status ((Get-Text 'Console.Progress.Run') -f $Index, $Count, $Name) ` -PercentComplete ([math]::Round(($Index - 1) / [math]::Max($Count, 1) * 100)) } function Complete-RunProgress { [CmdletBinding()] [OutputType([void])] param() Complete-CheckProgress Write-Progress -Id $script:ProgressRunId -Activity (Get-Text 'Console.Progress.Activity') -Completed } function Write-CheckProgress { <# .SYNOPSIS The bar beneath the Run's, for a Check that is waiting on something. Emits nothing. .DESCRIPTION Emitting nothing is load-bearing for the same reason as Wait-Sample: this is called inside sampling loops whose output is the readings themselves. .PARAMETER Seconds For a Check that runs for a set time: the seconds so far, shown as "15 von 60 s". #> [CmdletBinding(DefaultParameterSetName = 'Step')] [OutputType([void])] param( [Parameter(Mandatory, ParameterSetName = 'Step')][string]$Status, [Parameter(Mandatory, ParameterSetName = 'Step')][double]$Step, [Parameter(Mandatory, ParameterSetName = 'Seconds')][double]$Seconds, [Parameter(Mandatory)][double]$Of ) if ($PSCmdlet.ParameterSetName -eq 'Seconds') { $Status = (Get-Text 'Console.Progress.Seconds') -f [int]$Seconds, [int]$Of $Step = $Seconds } $percent = Get-ProgressPercent -Step $Step -Of $Of $shown = '{0}|{1}' -f $percent, $Status if ($shown -eq $script:ProgressLastShown) { return } $script:ProgressLastShown = $shown Write-Progress -Id $script:ProgressCheckId -ParentId $script:ProgressRunId ` -Activity (Get-Text 'Console.Progress.CheckActivity') -Status $Status -PercentComplete $percent } function Complete-CheckProgress { [CmdletBinding()] [OutputType([void])] param() if ($null -eq $script:ProgressLastShown) { return } $script:ProgressLastShown = $null Write-Progress -Id $script:ProgressCheckId -ParentId $script:ProgressRunId ` -Activity (Get-Text 'Console.Progress.CheckActivity') -Completed } |