0

我对 Powershell 很陌生。我试图在特定进程运行时获得 CPU 最大和平均利用率。我正在使用下面的脚本,但当时我只得到平均 CPU 利用率。

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

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

4

2 回答 2

0

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

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

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

如果您愿意,这是我的代码:

  • 启动 cmd 进程
  • 将处理时间记录到数组中。
    • 注意:处理时间以秒为单位,并且是累积的(即不断累加)
    • 我们必须做一些减法以获得处理时间之间的“增量”或差异。此外,每秒采样一次(而不是每 2 秒一次)使我们的计算变得更容易。
    • 我将增量乘以 10 以获得粗略的 % CPU 值
  • 一旦 cmd 进程结束,它就会退出 while 循环。
  • 然后,我们使用 Measure-Object 获取数组,并计算 min、max 和 avg 值
  • 然后,我们将输出通过管道传输到文本文件(或者将 $array 传输到文本文件,您可以在其中分析 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?

根据您的评论,我认为第 2 部分是您想要的……这需要更多时间和解释。我可以给你一个关于你必须做什么的基本概述。

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

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

  1. “包装”您使用 PowerShell 脚本启动的任何进程。即采用上述脚本,并使用它来启动 cmd 进程。这样,每个 PowerShell 脚本控制一个正在记录和测量的单个 cmd 进程,并且会给你很好的数字。
  2. 对于当前正在运行的进程,您必须使用如下脚本:

.

$cmdProcess = Get-Process cmd
$cmdProcess | foreach{
    $avg = $_.CPU / ([datetime]::Now - [datetime]$_.StartTime).TotalSeconds
    Write-Host "PID: $($_.Id)  CPU: $($_.CPU)  Average: $avg"
}

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

于 2013-07-05T18:07:34.147 回答
0

如果您想每 2 秒采样一次,并在 cmd.exe 运行的整个期间显示 max、min、ave,那么下面的代码将起作用。但是,如果您想每两秒对数据进行一次采样并显示该 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 更新以修复错误 - 正在收集进程使用的总时间(与 2 秒间隔内的增量相比)**

于 2013-07-05T17:42:56.593 回答