PowerShell - 如何在文本文件中执行脚本并保存结果

时间:2013-07-05 11:35:00

标签: powershell scripting

我对Powershell很新。我正在尝试在特定进程运行时获得CPU最大值和平均利用率。我使用的是以下脚本,但我当时只获得了平均CPU利用率。

Get-WmiObject win32_processor | Measure-Object -property LoadPercentage -Average | Select Average

请帮助我使用的示例脚本“如何在特定进程运行时每2秒获得CPU最大值和平均利用率,并将结果数据存储在文本文件中” ....

2 个答案:

答案 0 :(得分:0)

如果要每2秒进行一次采样,并在cmd.exe运行的整个时间段内显示max,min,ave,则以下代码将起作用。但是如果你想每2秒对数据进行一次采样并显示2秒间隔的最大值,最小值,平均值,则所有3个都是相同的(因为在该间隔期间你只有1个样本)。您必须更频繁地采样(例如每0.2秒),然后在每两秒间隔后重置$ stats数组。下面的代码不是为此而设计的。

$cmdProcess = start-process cmd -passthru
$delay = 2
$stats = @()
$previous = ($cmdProcess|Get-Process).cpu
while (-not $cmdProcess.HasExited) {
  $latest = $cmdProcess|Get-Process
  $delta = $latest.cpu - $previous
  $delta
  $stats += $delta
  $previous = $latest.CPU
  sleep $delay
}
$stats|% {$_/$delay}|measure -max -min -ave

**更新7/8修复bug - 收集进程使用的总时间(vs delta超过2秒间隔)**

答案 1 :(得分:0)

Measure-Object命令为Max,Min和Average提供相同值的原因是因为您只传递一个样本(即一个样本的Max,Min和Average始终相同) )。

要获得平均值,您需要捕获许多样本(例如,只要进程“cmd”正在运行)。我将该信息存储在一个数组中,然后当我将数组传递给我的Measure-Object cmdlt时,它会给我正确的Max,Min,Average。

编辑第1部分:(重写以更正代码)

如果你想:

,这是我的代码
  • 启动cmd进程
  • 将处理时间记录到数组中。
    • 注意:处理时间以秒为单位,且是累积的(即不断累加)
    • 我们必须进行一些减法以获得“delta”或处理时间之间的差异。此外,每秒采样(而不是每2秒)使我们的计算更容易。
    • 我将delta乘以10得到粗略的%CPU值
  • cmd进程结束后,将退出while循环。
  • 然后,我们使用Measure-Object获取数组,并计算min,max和avg值
  • 然后我们将输出管道传输到文本文件(或者替代方法是将$数组管道传输到文本文件,在那里您可以随时间分析CPU)。

$cmdProcess = start-process cmd -passthru

$array = @()
$LastCPU = $CmdProcess.CPU * 10

while(-not $cmdProcess.HasExited)
{
    $CurrentCPU = $CmdProcess.CPU*10
    $array += $CurrentCPU - $LastCPU
    $LastCPU = $CurrentCPU
    sleep 1
}

$array | Measure-Object -Average -Maximum -Minimum | Out-File c:\Output.txt

编辑第2部分:

你原来的问题实际上是两个问题:

  1. 为什么[below]脚本只返回平均CPU利用率? - 答案就是我上面的解释。
  2. 如何从特定/多个进程(特别是多个cmd.exe)获取最小,最大,平均CPU?
  3. 根据你的评论,我认为第2部分是你想要的...这需要更多的时间和解释。我可以给你一个基本的概述,你将要做什么。

    如果使用上述脚本,则可以控制何时启动脚本并可以准确测量CPU。如果cmd.exe已在运行,那么您无法获得准确的数字(即,如果该进程已运行10个小时,您将获得该进程使用的CPU时间的总秒数。您不能轻易地 从中获取最小和最大CPU,但使用StartTime属性,您可以获得平均值。)

    我看到两种方法可以得到你想要的东西:

    1. “换行”使用PowerShell脚本启动的任何进程。即使用上面的脚本,并使用它来启动cmd进程。这样,每个PowerShell脚本都可以控制正在记录和测量的单个cmd进程,并为您提供良好的数字。
    2. 对于当前正在运行的进程,您必须使用如下脚本:
    3. $cmdProcess = Get-Process cmd
      $cmdProcess | foreach{
          $avg = $_.CPU / ([datetime]::Now - [datetime]$_.StartTime).TotalSeconds
          Write-Host "PID: $($_.Id)  CPU: $($_.CPU)  Average: $avg"
      }
      

      这是获取所有“cmd”进程的地方,遍历每个进程,根据运行时间计算平均CPU利用率,并显示结果(可以发送到文件或任何地方)。然后,您可以将其用作另一个运行的较大循环的一部分,并记录所有进程的CPU时间(类似于第一个脚本)。一个完整的更大的最终剧本将超出这个问题的范围,你将不得不自己做更多的研究来完成它,但这应该给你一个良好的开端。