本文介绍了如何使用 PowerShell 监控进程的 CPU 使用率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个 PowerShell 脚本来监控 SQL Server 进程的 CPU 利用率百分比.我想每天记录这个数字的快照,以便我们可以随着时间的推移对其进行监控并观察趋势.

I'm trying to write a PowerShell script to monitor % CPU utilization of a SQL Server process. I'd like to record snapshots of this number every day so we can monitor it over time and watch for trends.

我在网上的研究说这个 WMI 查询应该给我我想要的:

My research online said this WMI query should give me what I want:

Get-WmiObject -Query "SELECT PercentProcessorTime FROM win32_PerfFormattedData_PerfProc_Process WHERE Name='SqlServr'"

当我运行 WMI 查询时,我通常会得到一个介于 30-50% 之间的值

When I run the WMI query I usually get a value somewhere between 30-50%

但是,当我在 Resource Monitor 中查看进程时,它的平均 CPU 使用率通常低于 1%

However, when I watch the process in Resource Monitor it usually averages at less than 1% CPU usage

我知道 WMI 查询只是返回 CPU 使用率的快照,而不是很长一段时间内的平均值,所以我知道这两者不能直接比较.即便如此,我认为快照通常应该小于 1%,因为 Resource Monitor 平均值小于 1%.

I know the WMI query is simply returning snapshot of CPU usage rather than an average over a long period of time so I know the two aren't directly comparable. Even so, I think the snapshot should usually be less than 1% since the Resource Monitor average is less than 1%.

有没有人知道为什么会有这么大的差异?以及如何准确测量进程的 CPU 使用率?

Does anybody have any ideas on why there is such a large discrepancy? And how I can get an accurate measurement of the CPU usage for the process?

推荐答案

过去几天我学到的关于 WMI 和性能计数器的一切.

Everything I've learned about WMI and performance counters over the last couple of days.

WMI 代表 Windows 管理规范.WMI 是向 WMI 系统和 Windows COM 子系统注册的类的集合.这些类称为提供程序,具有任意数量的公共属性,可在查询时返回动态数据.

WMI stands for Windows Management Instrumentation. WMI is a collection of classes registered with the WMI system and the Windows COM subsystem. These classes are known as providers and have any number of public properties that return dynamic data when queried.

Windows 预装了大量 WMI 提供程序,可为您提供有关 Windows 环境的信息.对于这个问题,我们关注 Win32_PerfRawData* 提供程序 以及基于它构建的两个包装器.

Windows comes pre-installed with a large number of WMI providers that give you information about the Windows environment. For this question we are concerned with the Win32_PerfRawData* providers and the two wrappers that build off of it.

如果您直接查询任何 Win32_PerfRawData* 提供程序,您会注意到它返回的数字看起来很吓人.这是因为这些提供程序提供了原始数据,您可以使用它来计算您想要的任何内容.

If you query any Win32_PerfRawData* provider directly you'll notice the numbers it returns are scary looking. That's because these providers give the raw data you can use to calculate whatever you want.

为了更轻松地使用 Win32_PerfRawData* 提供程序,Microsoft 提供了两个包装器,可在查询时返回更好的答案,PerfMon 和 Win32_PerfFormattedData* 提供程序.

To make it easier to work with the Win32_PerfRawData* providers Microsoft has provided two wrappers that return nicer answers when queried, PerfMon and Win32_PerfFormattedData* providers.

好的,那么我们如何获得进程的 CPU 利用率百分比呢?我们有三个选择:

Ok, so how do we get a process's % CPU utilization? We have three options:

  1. 从 Win32_PerfFormattedData_PerfProc_Process 提供程序获取格式良好的数字
  2. 从 PerfMon 获取格式良好的数字
  3. 使用 Win32_PerfRawData_PerfProc_Process 计算我们自己的 CPU 利用率百分比

我们会看到选项 1 存在一个错误,因此它在所有情况下都不起作用,即使这是互联网上通常给出的答案.

We will see that there is a bug with option 1 so that it doesn't work in all cases even though this is the answer usually given on the internet.

如果您想从 Win32_PerfFormattedData_PerfProc_Process 获取此值,您可以使用问题中提到的查询.这将为您提供此进程所有线程的 PercentProcessorTime 值的总和.问题是,如果有 1 个以上的核心,则该总和可能大于 100,但此属性最大为 100.因此,只要此进程的所有线程的总和小于 100,您就可以通过将进程的线程除以得到答案PercentProcessorTime 属性由机器的核心数决定.

If you want to get this value from Win32_PerfFormattedData_PerfProc_Process you can use the query mentioned in the question. This will give you the sum of the PercentProcessorTime value for all of this process's threads. The problem is that this sum can be >100 if there is more than 1 core but this property maxes out at 100. So, as long as the sum of all this process's threads is less than 100 you can get your answer by dividing the process's PercentProcessorTime property by the core count of the machine.

如果您想从 PowerShell 中的 PerfMon 获取此值,您可以使用 Get-Counter "\Process(SqlServr)\% Processor Time".这将返回一个介于 0 - (CoreCount * 100) 之间的数字.

If you want to get this value from PerfMon in PowerShell you can use Get-Counter "\Process(SqlServr)\% Processor Time". This will return a number between 0 - (CoreCount * 100).

如果您想自己计算此值,Win32_PerfRawData_PerfProc_Process 提供程序上的 PercentProcessorTime 属性将返回此进程已使用的 CPU 时间.因此,您需要拍摄两个快照,我们将它们称为 s1 和 s2.然后我们将执行 (s2.PercentProcessorTime - s1.PercentProcessorTime)/(s2.TimeStamp_Sys100NS - s1.TimeStamp_Sys100NS).

If you want to calculate this value for yourself the PercentProcessorTime property on the Win32_PerfRawData_PerfProc_Process provider returns the CPU time this process has used. So, you'll need to take two snapshots we'll call them s1 and s2. We'll then do (s2.PercentProcessorTime - s1.PercentProcessorTime) / (s2.TimeStamp_Sys100NS - s1.TimeStamp_Sys100NS).

这是最后一句话.希望能帮到你.

And that is the final word. Hope it helps you.

这篇关于如何使用 PowerShell 监控进程的 CPU 使用率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 18:43