Fine-tuning Get-Counter script for quicker execution - powershell

Below is my script to get process utilization of individual w3wp.exe app pools, the problem is each iteration takes about 2 seconds there are about 25 app pools. Can you please help me to fine tune the below script for faster execution.
gwmi win32_process -filter 'name="w3wp.exe"' | % {
$name=$_.name
$cmd = $pattern.Match($_.commandline).Groups[1].Value
$procid = $_.ProcessId
$tmp = (Get-Counter "\Process(*)\ID Process").CounterSamples | Where-Object {$_.CookedValue -eq $procid} | select -expand Path
$calc = [regex]::match($tmp,'\(([^\)]+)\)').Groups[1].Value
$cooked = (Get-Counter "\Process($calc)\% Processor Time").CounterSamples | Where-Object {$_.InstanceName -notlike '_total'} | select -expand CookedValue
$cpuper = [Math]::Round( ($cooked/2), 0)
echo $cpuper
}

It looks like Get-Counter has a minimum sample time of 1 second. Resulting in a minimum execution time of 1 second per call. Your best bet would be to get all the counters up front and then look for the counters you are interested in.
This does something like what you were doing. It prints the process ID and % processor time in a table.
$proc = 'w3wp'
$samples = get-counter '\Process($proc*)\ID Process', '\Process($proc*)\% Processor Time' | select -expand countersamples
$samples | group { Split-Path $_.Path } | ft #{ N='ID'; E={$_.Group[0].CookedValue} }, #{ N='% Processor'; E={[Math]::Round($_.Group[1].CookedValue/2, 0)} }

Related

Top 5 Processes with CPU % and Process ID using Powershell

I tried this script
Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' |
Select -ExpandProperty countersamples |
?{$_.instanceName -notmatch "^(idle|_total|system)$"} |
Sort -Descending cookedvalue |
Select -First 5 #{
L='ProcessName';
E={[regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value}
},
#{
L='CPU';
E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}
},
#{
L='ProcessId';
E={((Get-Counter "\Process([regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value)\ID Process" -ErrorAction SilentlyContinue).CounterSamples).Cookedvalue}
}
I am able to get ProcessName and CPU % columns but not ProcessID
ProcessName CPU ProcessId
----------- --- ---------
firefox#4 0.58%
svchost#11 0.19%
firefox#6 0.19%
dwm 0.10%
svchost#39 0.10%
Make sure you request both the % Processor Time and ID Process counter from each counter instance, then use Group-Object to group them together.
Worth noting is that you don't need regex to correlate the two, simply group on the first part of the counter path (\Process(notepad#3)). Regex is also not needed for extracting the process name, since each sample already has an InstanceName property with the corresponding process name.
Once you've correlated name + process ID + sample value, you can start sorting, and then finally format the CPU percentage:
Get-Counter '\Process(*)\ID Process','\Process(*)\% Processor Time' -ErrorAction SilentlyContinue |
ForEach-Object {
$_.CounterSamples |
Where-Object InstanceName -NotMatch '^(?:idle|_total|system)$' |
Group-Object {Split-Path $_.Path} |
ForEach-Object {
[pscustomobject]#{
ProcessName = $_.Group[0].InstanceName
ProcessId = $_.Group |? Path -like '*\ID Process' |% RawValue
CPUCooked = $_.Group |? Path -like '*\% Processor Time' |% CookedValue
}
} |Sort-Object CPUCooked -Descending |
Select-Object -First 5 -Property *,#{Name='CPUPercentage';Expression={'{0:P}' -f ($_.CPUCooked / 100 / $env:NUMBER_OF_PROCESSORS)}} -ExcludeProperty CPUCooked
}

powershell to return values like a task manager

I want to use the powershell to return values, likes task manager.
However, the item of network usage cannot return correctly.
How can I modify the code? Thanks a lot.
$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
while ($true) {
$tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process |
select-object -property Name, #{Name = "CPU"; Expression = {($_.PercentProcessorTime/$cores)}}, #{Name = "PID"; Expression = {$_.IDProcess}}, #{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, #{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, #{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, #{"Name"="Network"; Expression = {get-counter "\Process($_.Name)\IO Read Bytes/sec"}} |
Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
Sort-Object -Property CPU -Descending|
Select-Object -First 5;
cls
$tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network";
Start-Sleep 3
}
This code is modified from articles as follows:
1. CPU and memory usage in percentage for all processes in Powershell
2. https://superuser.com/questions/1314534/windows-powershell-displaying-cpu-percentage-and-memory-usage#new-answer?newreg=a9290345d72946db9c7f8fd2af10de0a
3. Powershell Script - list process with cpu, memory, disk usage
I add a variable $process to show the owner of each process, but there are missing some parameters. I cannot find any documents about Get-WmiObject Win32_PerfFormattedData_PerfProc_Process from microsoft, is that normal? The modified code as follows:
$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
$Process = Get-Wmiobject Win32_process -computername "myComputerName" | select *,#{Name='Owner';Expression={($_.GetOwner()).User}}
while ($true) {
$tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process |
select-object -property Name, #{Name = "CPU"; Expression = {($_.PercentProcessorTime/$cores)}}, #{Name = "PID"; Expression = {$_.IDProcess}}, #{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, #{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, #{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, #{"Name"="Network"; Expression = { $_.IOReadBytesPersec }}, #{Name="Username"; Expression = {($($Process | ?{$_.ProcessId -eq $Item.IDProcess})).Owner} |
Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
Sort-Object -Property CPU -Descending|
Select-Object -First 15;
cls
$tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network", "Username";
Start-Sleep 1
}
The modified part is referenced from https://powershell.org/forums/topic/getting-percentage-cpu-time-and-owner-for-processes/
Guo-Jyun Zeng, welcome to SO.
First and foremost, the reason your 'Network' section isn't showing anything is because variable expansion is failing. Let me explain--while PowerShell understands basic variables to expand inside of double-quoted strings, it does not directly understand slightly more complex objects that have their own properties. So the problem you're having is here:
#{"Name"="Network"; Expression = {get-counter "\Process($_.Name)\IO Read Bytes/sec"}}
Since '$_.Name' is inside the double-quotes, PowerShell doesn't know what to do with it. There are a couple of ways you can easily accommodate this:
#{"Name"="Network"; Expression = {get-counter "\Process($($_.Name))\IO Read Bytes/sec"}}
or using string tokens:
#{"Name"="Network"; Expression = {get-counter ("\Process({0})\IO Read Bytes/sec" -f $_.Name)}}
However, in my tests to reproduce, simply running Get-Counter returns a complex object. That is, an object that has it's own properties and methods so this shouldn't work anyway. In targeting the resulting property I thought you'd be after (Get-Counter "\Process(ProcessName)\IO Read Bytes/sec").CounterSamples.CookedValue, the script never returned data at all--like the Get-Counters were taking too long or something.
However, 'Win32_PerfFormattedData_PerfProc_Process' already appears to have an equivalent property for the counter you seem to want data for: IOReadBytesPersec.
The only thing I'd note is that both that property and the Process-specific performance counter for 'IO Read Bytes/sec' count ALL I/O, not just network. In fact, looking at the processor object, I couldn't find any counters that were specific to Network-only.
Your CPU shows nothing when I run it because you're trying to divide by 0 in a lot of cases. Looking at PercentProcessorTime, it doesn't specify anything about an aggregate number of all processors. I wouldn't assume the load is divided across the cores as your code does--I could be wrong tho.
Finally, as a point of performance, you can significantly lessen the hardware impact of your script by rearranging some of the things you're doing:
Explicitly request the desired properties from 'Win32_PerfFormattedData_PerfProc_Process' so it doesn't default to all properties.
Consolidate the Select-Object -First 5 with your first Select-Object so you're only working on those 5 in the rest of the loop.
Here is some slightly modified code to show some of the changes I described:
$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
while ($true) {
$tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process |
select-object -First 5 -Property Name, #{Name = "CPU"; Expression = {($_.PercentProcessorTime)}}, #{Name = "PID"; Expression = {$_.IDProcess}}, #{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, #{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, #{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, #{"Name"="Network"; Expression = { $_.IOReadBytesPersec }} |
Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
Sort-Object -Property CPU -Descending
cls
$tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network";
Start-Sleep 3
}

How can know the usage of CPU of a windows service in an interval of time with PowerShell?

I am a beginner with PowerShell, How can know the usage of CPU of a windows service in an interval of time (for example for one hour) with PowerShell?
Something like this:
Get-Service | Get-counter
Thank so much
For CPU usage you need to use the get-process commandlet and then map the process name with the corresponding service.
Here is one of the past discussion thread where the get-process is discussed
Listing processes by CPU usage percentage in powershell
Sample code here
$Details = #()
$AllRunningServices = Get-CimInstance -class win32_service | Where-Object {$_.State -eq 'Running'} | Select-Object ProcessId , Name
foreach($procid in $AllRunningServices)
{
$Details += Get-Process | Where-Object {$_.Id -eq $procid.ProcessId} | Select-Object ProcessName, Id, CPU , #{Name = "serviceName" ; Expression={$procid.Name}}
}
$Details |Sort-Object -Property CPU -Descending | ft

Listing processes by CPU usage percentage in powershell

How does one lists the processes using CPU > 1% by piping the output from Get-Process to Where-Object?
Complete beginner to powershell all i can think is something like this
Get-Process | Where-Object { CPU_Usage -gt 1% }
If you want CPU percentage, you can use Get-Counter to get the performance counter and Get-Counter can be run for all processes. So, to list processes that use greater than say 5% of CPU use:
(Get-Counter '\Process(*)\% Processor Time').CounterSamples | Where-Object {$_.CookedValue -gt 5}
This will list the processes that was using >5% of CPU at the instance the sample was taken. Hope this helps!
There are several points to note here:
first, you have to use the $_ variable to refer to the object currently coming from the pipe.
second, Powershell does not use % to express percentage -- instead, % represents the modulus operator. So, when ou want percentage, you have to transform your number by yourself by simply multiplying it by 0.01.
third, the Get-Process cmdlet does not have a field CPU_Usage; a summary on its output can be found here. About the field CPU is says: "The amount of processor time that the process has used on all processors, in seconds." So be clear on what you can expect from the numbers.
Summarizing the command can be written as
Get-Process | Where-Object { $_.CPU -gt 100 }
This gives you the processes which have used more than 100 seconds of CPU time.
If you want something like a relative statement, you first have to sum up all used times, and later divide the actual times by the total time. You can get the total CPU time e.g. by
Get-Process | Select-Object -expand CPU | Measure-Object -Sum | Select-Object -expand Sum
Try to stack it together with the previous command.
Further improving earlier answers by adding dynamic detection of the number of logic cores so the percentage can be adjusted back to what us common mortals expect to see, where 100% means all of the CPU bandwidth of the machine, and there is no value greater than 100%. Includes a filter set at 10%, which one can adjust as appropriate. The assumption is that people will be interested in finding processes with high overload processor usage and not want to list the numerous idle processes of the machine.
$NumberOfLogicalProcessors=(Get-WmiObject -class Win32_processor | Measure-Object -Sum NumberOfLogicalProcessors).Sum
(Get-Counter '\Process(*)\% Processor Time').Countersamples | Where cookedvalue -gt ($NumberOfLogicalProcessors*10) | Sort cookedvalue -Desc | ft -a instancename, #{Name='CPU %';Expr={[Math]::Round($_.CookedValue / $NumberOfLogicalProcessors)}}
Sample output:
InstanceName CPU %
------------ -----
_total 100
idle 100
I was looking for a solution to get cpu, mem utilization by process. All solutions I tried where I would get the cpu but those numbers were not matching with taskmanager. So I wrote my own. Following will provide accurate cpu utilization by each process. I tested this on a I7 laptop.
$Cores = (Get-WmiObject -class win32_processor -Property numberOfCores).numberOfCores;
$LogicalProcessors = (Get-WmiObject –class Win32_processor -Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;
$TotalMemory = (get-ciminstance -class "cim_physicalmemory" | % {$_.Capacity})
$DATA=get-process -IncludeUserName | select #{Name="Time"; Expression={(get-date(get-date).ToUniversalTime() -uformat "%s")}},`
ID, StartTime, Handles,WorkingSet, PeakPagedMemorySize, PrivateMemorySize, VirtualMemorySize,`
#{Name="Total_RAM"; Expression={ ($TotalMemory )}},`
CPU,
#{Name='CPU_Usage'; Expression = { $TotalSec = (New-TimeSpan -Start $_.StartTime).TotalSeconds
[Math]::Round( ($_.CPU * 100 / $TotalSec) /$LogicalProcessors, 2) }},`
#{Name="Cores"; Expression={ ($Cores )}},`
#{Name="Logical_Cores"; Expression={ ($LogicalProcessors )}},`
UserName, ProcessName, Path | ConvertTo-Csv
Or as [pscustomobject]:
$cpu = Get-WmiObject –class Win32_processor -Property NumberOfCores, NumberOfLogicalProcessors
$mem = (Get-CimInstance -class cim_physicalmemory | measure capacity -sum).sum
$epoch = get-date(get-date).ToUniversalTime() -uformat "%s"
get-process -IncludeUserName |
% {
if ($_.starttime -gt 0) {
$ts = (New-TimeSpan -Start $_.StartTime -ea si).TotalSeconds
$cpuusage = [Math]::Round( $_.CPU * 100 / $ts / $cpu.numberoflogicalprocessors, 2)
} else {
$cpuusage = 0
}
[pscustomobject] #{
"Time" = $epoch
"Total_RAM" = $mem
"CPU_Usage" = $cpuusage
"Cores" = $cpu.numberofcores
"Logical Cores" = $cpu.numberoflogicalprocessors
"UserName" = $_.username
"ProcessName" = $_.processname
"Path" = $_.path
"CPU" = $_.CPU
"ID" = $_.ID
"StartTime" = $_.StartTime
"Handles" = $_.Handles
"WorkingSet" = $_.WorkingSet
"PeakPagedMemorySize" = $_.PeakPagedMemorySize
"PrivateMemorySize" = $_.PrivateMemorySize
"VirtualMemorySize" = $_.VirtualMemorySize
}
}
In addition to Get-Counter, you can also use Get-WmiObect to list and filter processes.
powershell "gwmi Win32_PerfFormattedData_PerfProc_Process -filter 'PercentProcessorTime > 1' | Sort PercentProcessorTime -desc | ft Name, PercentProcessorTime"
Alternatively, for Get-Counter, here is an example showing number format conversion to get rid of the annoying decimal places of the CookedValue.
In addition to filtering, this example also illustrates sorting, limiting columns, and output formatting:
powershell "(Get-Counter '\Process(*)\% Processor Time').Countersamples | Where cookedvalue -gt 3 | Sort cookedvalue -Desc | ft -a instancename, #{Name='CPU %';Expr={[Math]::Round($_.CookedValue)}}"
Get-Process is not the right cmdlet as it doesn't provide instantaneous CPU utilization.
You can also get the total load for all processors:
powershell "gwmi win32_processor | Measure-Object LoadPercentage -Average | ft -h Average"
Or,
typeperf -sc 4 "\Processor(_Total)\% Processor Time"
I'd like to Add my version of code just to assist anyone that is having trouble with the same issues.
I needed one that gave me the CPU and Memory and this my take on the subject. It can export over time if you setup a scheduled task in windows, and it appends to a CSV file output and you can get multiple processes.
$Cores = (Get-WmiObject -class win32_processor -Property numberOfCores).numberOfCores;
$LogicalProcessors = (Get-WmiObject –class Win32_processor -Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;
$TotalMemory = (get-ciminstance -class "cim_physicalmemory" | % {$_.Capacity})
#EDIT the PATH for the CSV output to be located
$PATH = "C:\temp"
#You can add more processes here as variables or just CommaSeperate them like below
$Process1 = 'explorer'
$Process2 = 'chrome'
Get-Process -Name $Process1,$Process2 | select #{N="TimeStamp";E={Get-Date -Format 'dd/MM/yyyy HH:mm:ss.fff'}},
ID,
name,
Handles,
PeakPagedMemorySize,
PrivateMemorySize,
VirtualMemorySize,
#{Name="Memory_MB"; Expression = {[Math]::Round(($_.workingSet / 1mb),2)}},
#{Name='CPU_Usage'; Expression = { $TotalSec = (New-TimeSpan -Start $_.StartTime).TotalSeconds [Math]::Round( ($_.CPU * 100 / $TotalSec) /$LogicalProcessors, 2) }},
#{Name="Cores"; Expression={ ($Cores )}},
#{Name="Logical_Cores"; Expression={ ($LogicalProcessors )}},
Path | Export-Csv -Path "$PATH\CPU_MEMORY_$env:COMPUTERNAME.csv" -NoTypeInformation -Append
I know this is above the OP's question and goes a bit further but I hope this helps!
To invoke vs. multible servers in parallel, and return process, cpu usage, servername, and corecount the following works well.
It will take 10 samples over 10sec and average the value. You can change this with the MaxSamples parameter.
I reckon its a less elegant version of what Emrah Saglam is doing, i just get scared and confused by all his pipes :)
$allServers = "server1", "PC001", "server2"
#Change value of MaxSamples to the number of samples to take. Samples are taken in 1sec intervals
$CPUUsage = Invoke-Command -ComputerName $allServers -ScriptBlock {
$counters = (Get-Counter "\Process(*)\% Processor Time" -MaxSamples 10).CounterSamples | Sort-Object -Property CookedValue -Descending
[int]$coreCount = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors
$counters | ForEach-Object {
Add-Member -MemberType NoteProperty -Name "CPU_PCT" -Value ([math]::Round($_.CookedValue / $coreCount))[0] -InputObject $_
Add-Member -MemberType NoteProperty -Name "Host" -Value ($_.Path -replace "^\\\\|\\process.*$","") -InputObject $_
Add-Member -MemberType NoteProperty -Name "CoreCount" -Value $coreCount -InputObject $_
}
$counters | Select-Object InstanceName,CPU_PCT,Host,Path,CoreCount
}
#Unhash to see all samples:
#$CPUUsage | Sort-Object -Property Host,CPU_PCT -Descending | Select-Object -Property Host,InstanceName,CPU_PCT,Path,CoreCount | Out-GridView -Title "CPU Usage"
#Group samples, add wanted values and take average. Add values to new object
$CPUUsageGrouped = $CPUUsage | Group-Object -Property InstanceName,Host
$CPUUsageGrouped | ForEach-Object {
Add-Member -MemberType NoteProperty -Name "CPUavg" -Value (($_.Group.CPU_PCT | Measure-Object -Sum).Sum / $_.Count) -InputObject $_
Add-Member -MemberType NoteProperty -Name "CPUmin" -Value ($_.Group.CPU_PCT | Sort-Object)[0] -InputObject $_
Add-Member -MemberType NoteProperty -Name "CPUmax" -Value ($_.Group.CPU_PCT | Sort-Object)[$_.Count -1] -InputObject $_
Add-Member -MemberType NoteProperty -Name "Host" -Value $_.Group.Host[0] -InputObject $_
Add-Member -MemberType NoteProperty -Name "CoreCount" -Value $_.Group.CoreCount[0] -InputObject $_
Add-Member -MemberType NoteProperty -Name "InstanceName" -Value $_.Group.InstanceName[0] -InputObject $_
}
#Sort the grid view with the build in search functions
$CPUUsageGrouped | Sort-Object -Property Host,CPUavg -Descending | Select-Object -Property Host,InstanceName,CPUavg,CoreCount,CPUmin,CPUmax | Out-GridView -Title "CPU Usage"
How about this for one process?
$sleepseconds = 1
$numcores = 4
$id = 5244
while($true) {
$cpu1 = (get-process -Id $id).cpu
sleep $sleepseconds
$cpu2 = (get-process -Id $id).cpu
[int](($cpu2 - $cpu1)/($numcores*$sleepseconds) * 100)
}
$Result = Invoke-Command -ComputerName $ServerName -ScriptBlock {
Get-Counter "\Process(*)\% Processor Time" -ErrorAction SilentlyContinue `
| Select-Object -ExpandProperty CounterSamples `
| Where-Object {$_.Status -eq 0 -and $_.instancename -notin "_total", "idle", "" -and $_.CookedValue/$env:NUMBER_OF_PROCESSORS -gt 0} `
| Sort-Object CookedValue -Descending `
| Select-Object #{N="ServerName";E={$env:COMPUTERNAME}},
#{N="ProcessName";E={
$friendlyName = $_.InstanceName
try {
$procId = [System.Diagnostics.Process]::GetProcessesByName($_.InstanceName)[0].Id
$proc = Get-WmiObject -Query "SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId =$procId"
$procPath = ($proc | where { $_.ExecutablePath } | select -First 1).ExecutablePath
$friendlyName = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($procPath).FileDescription
} catch { }
$friendlyName
}},
#{N="CPU_Percent";E={[System.Math]::Round(($_.CookedValue/$env:NUMBER_OF_PROCESSORS), 2)}},
#{N="TimeStamp";E={Get-Date -Format 'dd/MM/yyyy HH:mm:ss.fff'}} -First 10 `
$Result
}
# If you want to export result to your SQL Server table you can use DbaTools Powershell Modules.
$Result | Select -Property ServerName, ProcessName, CPU_Percent, TimeStamp | ConvertTo-DbaDataTable | Write-DbaDbTableData -SqlInstance $OutInstance -Database $OutDB -Schema dbo -Table WindowsTopCPUProcesses

Gathering the average values of Get-Counter outputs

I am currently trying to gather the average performance values of processes over a long period of time. Unfortunately, my script is only able to average all the gathered values, rather than the averages of the individual processes.
The script below is what I ended up with, which unfortunately doesn't give an output for each respective process:
Write-Output (Get-Counter -Counter "\Processor(_Total)\% Processor Time","\Process(Chrome)\% Processor Time" -SampleInterval 1 -MaxSamples 25 |
Select-Object -ExpandProperty CounterSamples |
Select-Object -ExpandProperty CookedValue |
Measure-Object -Average).Average
Ideally, I'd like to have an object with the output values formatted like so:
Output.chrome = 5.1283123
Output.total = 23.128732
This works for me:
Get-Counter -Counter "\Processor(_Total)\% Processor Time","\Process(Chrome)\% Processor Time" -SampleInterval 1 -MaxSamples 25 `
| Select-Object -ExpandProperty CounterSamples `
| Group-Object -Property InstanceName `
| ForEach-Object {
$_ | Select-Object -Property Name, #{n='Average';e={($_.Group.CookedValue | Measure-Object -Average).Average}};
} `
| Format-Table -AutoSize;
Output:
Name Average
---- -------
_total 11.8878325281858
chrome 4.80058851283048
It'd be easy enough to conditionally rename the names.
EDIT: Try this for PowerShell v2.0:
Get-Counter -Counter "\Processor(_Total)\% Processor Time","\Process(Chrome)\% Processor Time" -SampleInterval 1 -MaxSamples 25 `
| Select-Object -ExpandProperty CounterSamples `
| Group-Object -Property InstanceName `
| ForEach-Object {
$_ | Select-Object -Property Name, #{n='Average';e={(($_.Group | Measure-Object -Property CookedValue -Average).Average)}};
} `
| Format-Table -AutoSize;
Here is an approach:
$chrome = #()
$total = #()
$counterName = "\Processor(_Total)\% Processor Time","\Process(Chrome)\% Processor Time"
Get-Counter -Counter $counterName -SampleInterval 1 -MaxSamples 10 |
Select-Object -ExpandProperty countersamples | % {
$object = New-Object psobject -Property #{
InstanceName = $_.InstanceName
CookedValue = $_.CookedValue
}
if($object.InstanceName -eq "Chrome") {
$chrome += $object
} else {
$total += $object
}
}
$output = [PSCustomObject]#{
Chrome = ($chrome | Measure-Object -Average CookedValue).Average
Total = ($total| Measure-Object -Average CookedValue).Average
}
$output
Output:
Chrome Total
------ -----
5,61702990401208 31,4667298163454