在PowerShell中定时执行命令

时间:2010-08-18 15:17:11

标签: powershell time

是否有一种简单的方法可以在PowerShell中执行命令,例如Linux中的'time'命令? 我想出了这个:

$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds

但我想要像

这样简单的东西
time .\do_something.ps1

8 个答案:

答案 0 :(得分:287)

烨。

Measure-Command { .\do_something.ps1 }

请注意,Measure-Command的一个小缺点是您没有看到stdout输出。如果要查看输出,则可以使用.NET Stopwatch对象,例如:

$sw = [Diagnostics.Stopwatch]::StartNew()
.\do_something.ps1
$sw.Stop()
$sw.Elapsed

答案 1 :(得分:165)

您还可以从历史记录中获取最后一个命令,并从EndExecutionTime中减去StartExecutionTime

.\do_something.ps1  
$command = Get-History -Count 1  
$command.EndExecutionTime - $command.StartExecutionTime

答案 2 :(得分:90)

使用Measure-Command

实施例

Measure-Command { <your command here> | Out-Host }

Out-Host的管道允许您查看命令的输出,即 否则由Measure-Command消耗。

答案 3 :(得分:16)

Simples

function time($block) {
    $sw = [Diagnostics.Stopwatch]::StartNew()
    &$block
    $sw.Stop()
    $sw.Elapsed
}

然后可以用作

time { .\some_command }

您可能想要调整输出

答案 4 :(得分:4)

这是我写的一个与Unix time命令类似的函数:

function time {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$command,
        [switch]$quiet = $false
    )
    $start = Get-Date
    try {
        if ( -not $quiet ) {
            iex $command | Write-Host
        } else {
            iex $command > $null
        }
    } finally {
        $(Get-Date) - $start
    }
}

来源:https://gist.github.com/bender-the-greatest/741f696d965ed9728dc6287bdd336874

答案 5 :(得分:3)

使用秒表并格式化已用时间:

Function FormatElapsedTime($ts) 
{
    $elapsedTime = ""

    if ( $ts.Minutes -gt 0 )
    {
        $elapsedTime = [string]::Format( "{0:00} min. {1:00}.{2:00} sec.", $ts.Minutes, $ts.Seconds, $ts.Milliseconds / 10 );
    }
    else
    {
        $elapsedTime = [string]::Format( "{0:00}.{1:00} sec.", $ts.Seconds, $ts.Milliseconds / 10 );
    }

    if ($ts.Hours -eq 0 -and $ts.Minutes -eq 0 -and $ts.Seconds -eq 0)
    {
        $elapsedTime = [string]::Format("{0:00} ms.", $ts.Milliseconds);
    }

    if ($ts.Milliseconds -eq 0)
    {
        $elapsedTime = [string]::Format("{0} ms", $ts.TotalMilliseconds);
    }

    return $elapsedTime
}

Function StepTimeBlock($step, $block) 
{
    Write-Host "`r`n*****"
    Write-Host $step
    Write-Host "`r`n*****"

    $sw = [Diagnostics.Stopwatch]::StartNew()
    &$block
    $sw.Stop()
    $time = $sw.Elapsed

    $formatTime = FormatElapsedTime $time
    Write-Host "`r`n`t=====> $step took $formatTime"
}

使用样本

StepTimeBlock ("Publish {0} Reports" -f $Script:ArrayReportsList.Count)  { 
    $Script:ArrayReportsList | % { Publish-Report $WebServiceSSRSRDL $_ $CarpetaReports $CarpetaDataSources $Script:datasourceReport };
}

StepTimeBlock ("My Process")  {  .\do_something.ps1 }

答案 6 :(得分:0)

Measure-Command {echo "Good morning World!" | Write-Host}

来源-https://github.com/PowerShell/PowerShell/issues/2289#issuecomment-247793839

答案 7 :(得分:-3)

在答案中提到的任何性能测量命令中得出(不正确的)结论都只字不提。除了查看(自定义)函数或命令的裸调用时间外,还应考虑许多陷阱。

Sjoemel软件

'Sjoemelsoftware' voted Dutch word of the year 2015
Sjoemelen 的意思是作弊,由于大众汽车排放丑闻,出现了 sjoemelsoftware 一词。官方定义是“用于影响测试结果的软件”。

我个人认为,并非总是故意创建“ Sjoemelsoftware ”来欺骗测试结果,但可能源于与以下测试案例相似的适应实际情况。

作为示例,使用列出的性能评估命令Language Integrated Query (LINQ) (1),通常可以认为是 禁忌的完成方法,经常是,但并非总是如此!与本地PowerShell命令相比,将速度提高 40或更多的人,可能是错误地测量或得出了错误的结论。

关键是某些使用lazy evaluation(也称为延迟执行 (2))的.Net类(例如LINQ)。这意味着在将表达式分配给变量时,它似乎几乎立即完成,但实际上它尚未处理任何事情!

假设您dot-source. .\Dosomething.ps1命令具有PowerShell或更复杂的Linq表达式(为了便于说明,我将表达式直接嵌入了{{1} }):

Measure-Command

结果看起来很明显,后面的 Linq 命令比第一个 PowerShell 命令快约 40倍。不幸的是,不是那么简单...

让我们显示结果:

$Data = @(1..100000).ForEach{[PSCustomObject]@{Index=$_;Property=(Get-Random)}}

(Measure-Command {
    $PowerShell = $Data.Where{$_.Index -eq 12345}
}).totalmilliseconds
864.5237

(Measure-Command {
    $Linq = [Linq.Enumerable]::Where($Data, [Func[object,bool]] { param($Item); Return $Item.Index -eq 12345})
}).totalmilliseconds
24.5949

正如预期的那样,结果是相同的,但是如果您密切关注,您会发现显示PS C:\> $PowerShell Index Property ----- -------- 12345 104123841 PS C:\> $Linq Index Property ----- -------- 12345 104123841 结果要比$Linq结果花费更长的时间。
让我们通过仅获取结果对象的属性来具体测量那个

$PowerShell

检索PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds 14.8798 PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds 1360.9435 对象的属性比$Linq对象的属性花的时间要长 90倍

还要注意另一个陷阱,如果再次执行此操作,某些步骤的显示速度可能会比以前快很多,这是因为某些表达式已被缓存。

最重要的是,如果要比较两个功能之间的性能,则需要在用例中实现它们,从全新的PowerShell会话开始,然后根据完整解决方案的实际性能得出结论。

(1)有关PowerShell和LINQ的更多背景和示例,我建议您使用以下网站:High Performance PowerShell with LINQ
(2)我认为这两个概念之间存在细微的差异,例如惰性评估在需要时计算结果,该结果与延迟执行相关是在系统闲置

时计算得出的结果