Leptonator
Leptonator

Reputation: 3499

Powershell Process CPU checking

Have the following which works OK, but with an in issue in PowerShell:

$FileName = "E:\Work\ps\Inventory.htm"
$serverlist = "E:\Work\ps\Monitored_computers.txt"

foreach ($server in Get-Content $serverlist)
{
$servern=$server.split(",")[0]
$ip=$server.split(",")[1]

$cpu = gwmi Win32_PerfFormattedData_PerfProc_Process -Computer $servern -filter "Name <> '_Total' and Name <> 'Idle'" | Sort-Object PercentProcessorTime -Descending | where { $_.PercentProcessorTime -gt 0 }| select -First 1
if ($cpu.PercentProcessorTime -ge "92") {
write-host $servern ' ' $cpu.Name ' ' $cpu.PercentProcessorTime
}
}

I have seen some other code in PowerShell, that takes an Average but almost seems like an "average of an average" - which is meaningless. And, this is for overall CPU Usage

gwmi win32_processor | Measure-Object -property LoadPercentage -Average | Foreach {$_.Average}

Now, if we can take the same logic and apply for our process issue:

gwmi Win32_PerfFormattedData_PerfProc_Process | Sort-Object PercentProcessorTime -Descending | where { $_.PercentProcessorTime -gt 0 } | select -First 1 | Measure-Object -property PercentProcessorTime -Average | Foreach {$_.PercentProcessorTime}

What am trying to ask is: I do get the CPU Percentage, which seems to be a "point in time". How do locate the true CPU Percentage? This is why I am pointing out the average. I really want to get around the "point in time" part of this.

The point being, when we have seen on several occasions, a high CPU per process on a server, we login to the server and the high CPU has subsided. This is not to say, this has been each time, but we know that sometimes a CPU will spike and then quiet down.

Thanks for any insight!

Upvotes: 0

Views: 1338

Answers (2)

Leptonator
Leptonator

Reputation: 3499

Thanks to @TheMadTechnician I have been able to sort this out. I had a wrong component with

$_.Average

where I had

$_.PercentProcessorTime

and that would never work. Here is the correct script:

$serverlist = "D:\Work\ps\Monitored_computers.txt"

foreach ($server in Get-Content $serverlist) {
    $servern=$server.split(",")[0]
    $ip=$server.split(",")[1]

    $cpu = gwmi Win32_PerfFormattedData_PerfProc_Process -Computer $ip | `
     Where-Object {$_.Name -like "*tomcat*"}  | `
     Measure-Object -property PercentProcessorTime -Average | `
     Foreach {$_.Average}
    if ($cpu -ge "20") {
        write-host $servern $cpu ' has a tomcat process greater than 20'
    }
}

Upvotes: 0

TheMadTechnician
TheMadTechnician

Reputation: 36277

First issue, you are stuck at a Point In Time because when you execute your script it captures a snapshot of what is happening right then and there. What you are looking for is historical data, so you can figure out the average CPU usage of processes over a set amount of time, and pinpoint the process that's bogging down your CPU. Do you have performance monitors in place to track CPU usage for individual processes? You may need to setup performance logging if you want to be able to get the numbers you're looking for after the fact.

Secondly, I think that you misunderstand how Measure-Object works. If you run Get-Help on the cmdlet and check the Output you'll see that it outputs a GenericMeasureInfo object. This object will have a property for the relevant stat that you are looking for, which in your case is the Average property. It is not an average of an average, the most common usage I see for it is to calculate something, like a Sum or Average, and then output the value of that property.

Let's try a simple example...

Find the average size of the files in a folder. First we use Get-ChildItem to get a collection of files, and pipe it to Measure-Object. We will specify the -Average argument to specify that we want the Average calculated, and -Property length, so that it knows what to average:

GCI C:\Temp\* -file | Measure-Object -Average -Property length

This outputs a GenericMeasureInfo object like this:

Count    : 30
Average  : 55453155
Sum      : 
Maximum  : 
Minimum  : 
Property : Length

That lets me know that it had 30 files piped to it, and it found the Average for the Length property. Now, sometime you want to calculate more than one thing, so you can use more than one argument, such as -Sum and -Maximum, and those values will be populated as well:

Count    : 30
Average  : 55453155
Sum      : 1663594650
Maximum  : 965376000
Minimum  : 
Property : Length

So it looks like my average file is ~55MB, but out of the 1.6GB in the whole folder I've got one file that's 965MB! That file is undoubtedly skewing my numbers. With that output I could find folders that have multiple files, but one file is taking up over half of the space for the folder, and find anomalies... such as the ISO that I have saved to my C:\temp folder for some reason. Looks like I need to do some file maintenance.

Upvotes: 1

Related Questions