Below are far from perfect. But this is the closest that I could come up with to simulate the behavior of UNIX time
. I am sure that it can be improved.
I basically create a cmdlet that gets a script block, generates a process, and uses GetProcessTimes
to get Kernel, User, and Elapsed times.
After loading the cmdlet, just call it with
Measure-Time -Command {your-command} [-silent]
The -Silent
switch means there is no output generated from the command (for example, you are only interested in temporary measures)
So for example:
Measure-Time -Command {Get-Process;sleep -Seconds 5} -Silent
The output:
Kernel time : 0.6084039 User time : 0.6864044 Elapsed : 00:00:06.6144000
Here is the cmdlet:
Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class ProcessTime { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool GetProcessTimes(IntPtr handle, out IntPtr creation, out IntPtr exit, out IntPtr kernel, out IntPtr user); } "@ function Measure-Time { [CmdletBinding()] param ([scriptblock] $Command, [switch] $Silent = $false ) begin { $creation = 0 $exit = 0 $kernel = 0 $user = 0 $psi = new-object diagnostics.ProcessStartInfo $psi.CreateNoWindow = $true $psi.RedirectStandardOutput = $true $psi.FileName = "powershell.exe" $psi.Arguments = "-command $Command" $psi.UseShellExecute = $false } process { $proc = [diagnostics.process]::start($psi) $buffer = $proc.StandardOutput.ReadToEnd() if (!$Silent) { Write-Output $buffer } $proc.WaitForExit() } end { $ret = [ProcessTime]::GetProcessTimes($proc.handle, [ref]$creation, [ref]$exit, [ref]$kernel, [ref]$user ) $kernelTime = [long]$kernel/10000000.0 $userTime = [long]$user/10000000.0 $elapsed = [datetime]::FromFileTime($exit) - [datetime]::FromFileTime($creation) Write-Output "Kernel time : $kernelTime" Write-Output "User time : $userTime" Write-Output "Elapsed : $elapsed" } }
source share