Measure-Time.psm1
|
function Measure-Time { param ( [Parameter(Mandatory)] [ScriptBlock] $Command ) function Format-Duration { param ( [Parameter(Mandatory)] [TimeSpan] $TimeSpan ) $timeSpanStr = @() $timeComponents = @( @{"unit" = "h"; "value" = $TimeSpan.Hours }, @{"unit" = "m"; "value" = $TimeSpan.Minutes }, @{"unit" = "s"; "value" = $TimeSpan.Seconds }, @{"unit" = "ms"; "value" = $TimeSpan.Milliseconds } ) foreach ($timeComponent in $timeComponents) { if ($timeComponent.value -gt 0) { $timeSpanStr += "{0:0#}{1}" -f $timeComponent.value, $timeComponent.unit } } if ($timeSpanStr.Count -gt 0) { $timeSpanStr -join " " } else { "000ms" } } $JobApi = [JobApiLib.JobApi] $JobResourceUsage = [JobApiLib.JobApi+JobResourceUsage] try { $commandString = $Command.ToString().Trim() $jobHandle = $JobApi::CreateJobObject([IntPtr]::Zero, $null) $processInfo = [System.Diagnostics.ProcessStartInfo]::new("powershell", "-NoLogo -NoProfile -Command & { $commandString }") $processInfo.UseShellExecute = $false $processInfo.WorkingDirectory = (Get-Location).Path $subProcess = [System.Diagnostics.Process]::Start($processInfo) [void]$JobApi::AssignProcessToJobObject($jobHandle, $subProcess.Handle) $stopWatch = [System.Diagnostics.Stopwatch]::StartNew() $subProcess.WaitForExit() } finally { $stopWatch.Stop() $bufferSize = $JobApi::GetStructSize() $bufferPointer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($bufferSize) if ($jobHandle -ne [IntPtr]::Zero -and $JobApi::QueryInformationJobObject($jobHandle, 1, $bufferPointer, $bufferSize, [ref]0)) { $jobUsageData = [System.Runtime.InteropServices.Marshal]::PtrToStructure($bufferPointer, [type]$JobResourceUsage) $userTime = [TimeSpan]::FromTicks($jobUsageData.TotalUserTime) $kernelTime = [TimeSpan]::FromTicks($jobUsageData.TotalPrivilegedTime) $processorTime = $userTime + $kernelTime $wallTime = $stopWatch.Elapsed $cpuLoad = [math]::Round($processorTime.TotalSeconds / $wallTime.TotalSeconds * 100) $usage = "$cpuLoad%" $userTime = Format-Duration $userTime $kernelTime = Format-Duration $kernelTime $processorTime = Format-Duration $processorTime $wallTime = Format-Duration $wallTime # Write-Host "{ $commandString } $userTime user $kernelTime system $processorTime cpu $usage cpu% $wallTime total" Write-Host "{ $commandString } $userTime user $kernelTime system $usage cpu $wallTime total" } if ($bufferPointer -ne [IntPtr]::Zero) { [System.Runtime.InteropServices.Marshal]::FreeHGlobal($bufferPointer) } if ($jobHandle -ne [IntPtr]::Zero) { [void]$JobApi::CloseHandle($jobHandle) } } } # alias to Measure-Time Set-Alias -Name time -Value Measure-Time -Option AllScope Export-ModuleMember -Function Measure-Time Export-ModuleMember -Alias time |