Monitoring Windows Server with PowerShell

Perfmon – Visualizing Performance Counters in Windows Server

Did you know almost every agentless commercial monitoring soloution is actually running remote PowerShell commands we discuss in this article, to collect metric information?

Spoiler! they use invoke-comand

Monitoring the performance of a Windows server is crucial for ensuring its stability and reliability. It’s also a must-know when it comes to troubleshooting issues with services or applications in Windows Server environments.

One effective way to do this is by using Performance Counters. we can monitor Performance Counters via Performance Monitor in Windows Admin Center (which most people never use) or the classic built-in Perfmon.exe. In this article, we’ll explore performance counters, how to view them visually, and how to use PowerShell to list, get, and calculate their values.

What are Performance Counters?

Performance counters are metrics that provide valuable information about the performance of a system. They are essentially data points that measure various aspects of a system, such as CPU usage, disk I/O, memory usage, network traffic, and more.

In fact, with each Role Service deployment in Windows Server, the installation also deploys its related performance counters too. for instance, when you deploy Active Directory, a set of performance counters such as “\NTDS\DS Directory Searches/sec” will be implemented into the system. same for DNS, DHCP, Exchange Server, SharePoint Server, etc.

By monitoring these counters, you can identify potential issues and take corrective actions before they escalate into major problems.

How to View Performance Counters Visually

Windows provides a built-in tool called Performance Monitor (perfmon) that allows you to view performance counters visually. You can access perfmon by typing “perfmon” in the Run dialog box or by searching for it in the Start menu. Once opened, you can add the counters you want to monitor by clicking the “+” button and selecting the appropriate counter from the list.

How to List Performance Counters that are available with PowerShell

PowerShell provides several cmdlets that allow you to work with performance counters. To list all the available counters on a system, you can use the below command:

Get-Counter -ListSet *

This will display a list of all the available counter categories, such as Processor, Memory, Network Interface, and more.

How to get Performance Counter Values Using PowerShell

To get the value of a specific performance counter using PowerShell, you can use the “Get-Counter” cmdlet. For example, to get the current CPU usage percentage, you can run the following command:

Get-Counter '\Processor(_Total)\% processor time'

This will return the current value of the “% Processor Time” counter for the “_Total” processor category. note that the full combination of counter SetName, Category, and Name actually creates a full path, that we used to have access to the exact counter. in our case, ‘\Processor(_Total)\% processor time’ is the full path. so you now understand how counters are structured.

How to Get Average and Sum of Performance Counters in an Interval with PowerShell

PowerShell also allows you to calculate the average and sum of performance counter values over a specified interval. To do this, you can use the “Get-Counter” cmdlet with the “-MaxSamples” and “-SampleInterval” parameters. For example, to get the average CPU usage percentage over a 2-second interval of 3-Samples, you can run the following command:

Get-Counter '\processor(_total)\% processor time' -MaxSamples 3 -SampleInterval 2 | Select-Object -ExpandProperty CounterSamples | Measure-Object -Property CookedValue -Average

This will display the average value of 3 samples for the “% Processor Time” counter over a 2-second interval. so it must take ((1-3)*2) seconds to be done.

you can also use “-Continuous” to get samples instead of “-MaxSamples”, which will continuously get samples for you, and you need to stop it using Ctrl+C.

Example Challenge: Monitoring inbound network traffic in MegaByte per second (MBps) via PowerShell

The counter path is “\Network Interface(*)\Bytes Received/sec”. then we should get it like this:

PS C:\Windows\system32> Get-Counter '\Network Interface(*)\Bytes Received/sec' | Select-Object -ExpandProperty CounterSamples | Measure-Object -Property CookedValue -Sum

This command retrieves the value of the “Bytes Received/sec” counter for all network interfaces and calculates the sum of the cooked values over the sampling interval.

which for me, it returns:

Count    : 
Average  :
Sum      : 91104154.0636114
Maximum  :
Minimum  :
Property : CookedValue1

but as the counter path name indicates, it returns traffic in BytesPerSecond. then we can use a custom `Select-Object` expression, with Byte-to-MegaByte conversion easily with “/1MB”.

PS C:\Windows\system32> Get-Counter '\Network Interface(*)\Bytes Received/sec' | Select-Object -ExpandProperty CounterSamples | Measure-Object -Property CookedValue -Sum | Select-Object @{Name='MegaBytesReceivedPerSecond';Expression={($_.Sum)/1MB}}


As seen, I’m receiving a total of 89MB/s traffic, which is because of the full replication of a newly added DAG member šŸ˜‰


In conclusion, PowerShell provides a powerful set of tools for monitoring the performance of a Windows server using performance counters. By leveraging these tools, you can gain valuable insights into the health and performance of your system, allowing you to proactively identify and address potential issues before they become critical.

Now tap into your creativity, and start your own smart monitoring system that alerts you only when a specific series of ” if ( Condition ){} ” logic are met. isn’t that awesome? or start sending the performance counter values into visualization systems like Grafana.

Behrouz Amiri

Iā€™m an author, entrepreneur, and SysAdmin. I worked for many well-known enterprises during my career, and sill work for one, however, I always loved to write and contribute to the IT industry, and this led me here with you guys!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.