Skip to main content

Category filter

PowerShell script to get performance counter data from Windows

TL;DR

Use PowerShell scripts with Hexnode UEM’s Execute Custom Script remote action to get performance counter data from Windows device, helping IT admins investigate system slowdowns and resource bottlenecks. By executing the Get-Counter cmdlet, IT administrators can discover metric paths, monitor specific subsystems like CPU or disk latency, and isolate resource bottlenecks.

Executive Summary

When a managed Windows device encounters performance issues, Hexnode UEM administrators can execute PowerShell scripts to get performance counter data from those devices without interrupting the end user. The collected data helps administrators compare resource usage against expected levels, spot unusual activity, and narrow down potential causes of slow performance. Administrators can view the script output under Manage > Endpoints > [select the target Windows endpoint] > Action History > Show Output and use the results to narrow down potential causes before proceeding with further troubleshooting.

What is performance counter data on Windows?

Performance counters are built-in Windows components that measure system resource usage, recording metrics such as CPU utilization, available memory, disk read/write activity, and network traffic.

The PowerShell Get-Counter cmdlet retrieves this performance data, allowing administrators to examine resource usage, identify potential bottlenecks, and investigate device performance issues.

What is the Get-Counter cmdlet?

The Get-Counter cmdlet is a built-in Windows PowerShell utility that retrieves performance counter data via the command line. When administrators deploy a PowerShell script containing the Get-Counter cmdlet through Hexnode UEM’s Execute Custom Script remote action, the script runs on the selected managed Windows endpoint and collects the requested performance metrics.

Script details and requirements

The following table outlines the environment properties and deployment prerequisites required before executing the scripts:

Property Specification
Scripting Language PowerShell
File Extension .ps1
Deployment Method Hexnode UEM portal via Execute Custom Script remote action
OS Support Windows 10 (v1709+) and Windows 11 PCs/tablets.

Syntax of the Get-Counter cmdlet

The Get-Counter cmdlet supports two primary operations: counter set discovery, which lists available performance counter sets, and metric sampling, which collects performance counter readings on a Windows device.

Parameter set 1: Counter set discovery

Parameter set 2: Metric sampling

Parameter Description Input Type
Get-Counter A Windows PowerShell cmdlet that retrieves live performance counter data, such as CPU usage, available memory, disk I/O, and network statistics, from the Windows operating system. Cmdlet
-ListSet A parameter of the Get-Counter cmdlet that discovers and lists the available performance counter sets (categories) on a system. String (optional)
-Counter Specifies the performance counter paths to collect data from, such as CPU usage or disk activity. String[]
-SampleInterval Specifies the number of seconds between consecutive readings. Int32
-MaxSamples Specifies the total number of readings to collect for each counter. Int64

PowerShell deployment examples

Notes:

  • It is recommended to manually validate the script execution on a system before executing the action in bulk.
  • Hexnode will not be responsible for any damage/loss to the system on the behavior of the script.

Get all available counter sets

1. Get all available counter sets

Execute the following script through Hexnode UEM to retrieve a complete list of available performance counter sets from the target Windows device.

How the script works:

Component Function
* Wildcard character specifying that all available counter sets should be returned, including sets related to the processor, memory, physical disk, network interface, and system activity.

When to use the script:

PowerShell script to get all available counter sets script helps administrators identify which sets correspond to the system components they want to monitor and determine the appropriate counter paths to use when collecting performance data. For example, they can examine the listed sets to find counters related to processor, memory, or network activity.

Note:


This script can return a large amount of data. For enterprise deployments, use it primarily during initial discovery. Once the required counter paths are identified, use targeted scripts to collect specific performance metrics across the device fleet.

Screenshot of Hexnode UEM portal showing the console output of the script to get all available counter sets using the Execute Custom Script remote action under the Manage tab.

Fetch specific performance metrics

2. Fetch specific performance metrics

Deploy the following script via Hexnode UEM to retrieve performance counter data for a specific metric path obtained from the .PathsWithInstances property of the Get-Counter -ListSet command.

Syntax:

How the script works:

Component Function
“PathsWithInstances” Replace the placeholder with a valid performance counter path copied from the PathsWithInstances property returned by Script 1 (Get-Counter -ListSet *).

Screenshot of PowerShell output from the script to Get all available counter sets highlighting the PathsWithInstances field containing the performance counter paths available on a Windows device.

When to use the script:

Admins can deploy this script to troubleshoot device issues like app freezes, slow storage drives, or unresponsive applications. Querying a specific metric returns only the required data, reducing the overhead of querying entire counter categories and filtering out telemetry noise so administrators can isolate specific performance issues.

Example:

The following script retrieves the NTFS performance counter for operations taking longer than 30 seconds, helping administrators investigate slow file-saving operations or disk freezes on a managed Windows device:

How to read the output:

The numeric value shown beneath the CounterSamples field indicates the number of cluster allocation requests on drive C: that took longer than 30 seconds. 0 means no requests exceeded this duration, while 1 or higher indicates that one or more requests took longer than 30 seconds to complete.

Screenshot of Hexnode UEM portal showing the console output of the script to fetch NTFS disk latency performance metrics using the Execute Custom Script remote action under the Manage tab.

Fetch specific performance metrics over a time interval

3. Fetch specific performance metrics over a time interval

Execute the following PowerShell script through Hexnode UEM to get specific performance counter data at regular, repeating intervals.

Syntax:

How the script works:

Component Function
“PathsWithInstances” Replace the placeholder with a valid performance counter path copied from the PathsWithInstances property returned by Script 1 (Get-Counter -ListSet *).
-SampleInterval Parameter that specifies the time delay (in seconds) between each consecutive sample collection.
<Seconds> Placeholder to be replaced with the required interval in seconds.
-MaxSamples Specifies the total number of samples to collect during a single execution of the Get-Counter command.
<Total_Samples> Placeholder to be replaced with the required number of samples.

When to use the script:

Admins can deploy this script to investigate issues such as CPU usage spikes, memory usage fluctuations, slow disk operations, or sudden changes in network activity. Collecting multiple samples at regular intervals helps admins to determine whether these changes are momentary or systemic on a managed Windows device.

Example:

The following script collects three samples of the specified NTFS performance counter at two-second intervals to check whether long-running disk operations continue across multiple readings. Sampling completes automatically once all three samples have been collected.

Screenshot of Hexnode UEM portal showing the console output of the script to fetch NTFS disk performance metrics over a time interval using the Execute Custom Script remote action under the Manage tab.

Note:


The time required to collect performance counter samples depends on the configured sample interval and total sample count. For example, collecting 40 samples at 60-second intervals takes approximately 40 minutes. Ensure that the script’s execution timeout in Hexnode UEM is sufficient for the selected sampling duration. If the timeout is shorter, the script may stop before collecting all the requested samples.

Fetch alphabetical list of counter sets

4. Fetch alphabetical list of counter sets

Execute the following script through Hexnode UEM to retrieve all available performance counter sets sorted alphabetically and formatted into a clean, readable table.

How the script works:

Component Function
Sort-Object Cmdlet that sorts the retrieved counter sets.
-Property CounterSetName Parameter that specifies the property used to sort the items, ordering the categories alphabetically by CounterSetName.
Format-Table CounterSetName, CounterSetType The Format-Table cmdlet formats the results into a table displaying two specific properties:
  • CounterSetName: Displays the name of the performance counter category.
  • CounterSetType: Shows whether the category tracks a single system component (SingleInstance) or multiple items separately (MultiInstance).
-AutoSize Parameter that adjusts the column widths to fit the length of the text, preventing long names from being truncated.
Out-String Cmdlet that converts the formatted table output into plain text strings.
-Width Parameter that sets the line width to prevent long counter set names from wrapping or cutting off in the Hexnode UEM portal.
300 Value that sets the line display width to 300 characters. This can be adjusted as needed.

When to use the script:

Admins can deploy this script to view all available performance counter categories on a Windows device in alphabetical order and identify whether each counter set uses SingleInstance or MultiInstance before configuring targeted performance queries.

Screenshot of Hexnode UEM portal showing the console output of the script to fetch an alphabetical list of counter sets using the Execute Custom Script remote action under the Manage tab.

Fetch formatted path names using the Paths property

5. Fetch formatted path names using the Paths property

Deploy the following PowerShell script through Hexnode UEM to retrieve the standard metric path templates listed in the .Paths property of a specified performance counter set.

Syntax:

How the script works:

Component Function
“<CounterSetName>” Placeholder to be replaced with the exact category name (e.g., “Ldap Client”).
.Paths Property that extracts the canonical path templates for every metric in the counter set. For multi-instance sets, these paths include a wildcard placeholder (*) instead of specific system instances.

When to use the script:

Admins can deploy this script to retrieve valid counter path templates for a specific service or subsystem, such as LDAP, Active Directory, or DNS. The .Paths property returns the paths in the correct format, helping admins build targeted monitoring scripts without errors caused by incorrectly entered counter names or path syntax.

Example:

The following script retrieves all canonical counter path templates under the Ldap Client category, helping admins identify the exact metric paths for auditing domain controller lookup latency and authentication requests:

Screenshot of the Hexnode UEM portal showing the console output of the script to fetch formatted path names using the Paths property using the Execute Custom Script remote action under the Manage tab.

Fetch formatted path names using the PathsWithInstances property

6. Fetch formatted path names using the PathsWithInstances property

Execute the following PowerShell script via Hexnode UEM to retrieve counter paths mapped to the active hardware and process instances currently running on the endpoint (such as specific disk partitions, CPU cores, or background processes).

While the .Paths property returns canonical counter path templates containing a wildcard (*), the .PathsWithInstances property resolves those templates into live system instance identifiers (such as 0 C: and _Total). This allows administrators to extract the exact path strings needed to target specific resources without guessing disk index numbers or core IDs.

Syntax:

How the script works:

Component Function
“<CounterSetName>” Placeholder to be replaced with the exact category name (e.g., “PhysicalDisk”).
.PathsWithInstances Property that returns the counter paths for every metric in the selected category, resolved to the active hardware, volume, or process instances on the device (such as disk partitions like 0 C: or logical CPU core indices).

When to use the script:

Admins can run this script when troubleshooting problems on a specific drive—such as slow file transfers, freezing disks, or high disk queue lengths. If a device has multiple hard drives, this script shows the exact path for each drive (like 0 C:), allowing admins to copy and use that path to monitor only the drive experiencing issues.

Example:

The following script retrieves all counter paths for the PhysicalDisk category, showing the exact paths for the C: drive (0 C:) and the combined total (_Total).

Screenshot of the Hexnode UEM portal showing the script output window with a list of PhysicalDisk performance counter paths displaying actual drive names (0 C:) and (_Total) under the Action History tab of a managed Windows device.

Fetch a single value for each counter in a counter set

7. Fetch a single value for each counter in a counter set

Execute the following PowerShell script through Hexnode UEM to capture an instantaneous baseline snapshot of all metric values within a target single-instance counter set.

Syntax:

How the script works:

Component Function
“<CounterSetName>” Placeholder to be replaced with the exact category name (e.g., “Memory”).
.Paths Object property that extracts the canonical path strings for every performance metric defined within the target category.
$Counters Variable that stores the retrieved list of counter paths.
-Counter Accepts the array of path strings stored in $Counters and instructs Get-Counter to capture a single, point-in-time sample snapshot for each specified metric.

When to use the script:

Admins can use this script to retrieve all metrics within a single-instance counter set, such as Memory or System, in one execution. Viewing all related counter values together provides a snapshot of the subsystem’s current state, helping administrators identify unusual resource usage without querying each metric separately.

Example:

The following script retrieves all canonical counter paths under the Memory category and collects a single reading for each metric. This allows administrators to examine physical memory availability, commit limits, and memory pool allocations in a single execution:

Screenshot of the Hexnode UEM portal showing the script output window with a timestamp and readings for all Memory counters (such as page faults/sec, available bytes, and committed bytes) under the Action History tab of a managed Windows device.

Notes:


This script is intended exclusively for SingleInstance counter sets (such as Memory or System). Running bulk queries against MultiInstance categories (such as Process or PhysicalDisk) triggers wildcard queries across every active process or drive, which can cause Hexnode UEM script timeouts or unexpected process termination.

Display an object’s property value

8. Display an object’s property value

Execute the following PowerShell script through Hexnode UEM to capture a performance counter reading and expand all of its underlying property values (such as Path, InstanceName, CookedValue, RawValue, Timestamp, and status codes) into a detailed list view.

How the script works:

Component Function
$Counter Variable that stores the target metric path (\Process(Idle)\% Processor Time), a built-in counter that measures the percentage of time the processor is idle. This can be replaced with any metric path to inspect.
$Data Stores the performance counter data returned by Get-Counter, including the collected counter samples and related metadata.
-Counter Accepts the array of path strings stored in $Counters and instructs Get-Counter to capture a single, point-in-time sample snapshot for each specified metric.
$Data.CounterSamples Property that extracts the detailed sample data from the stored object.
Format-List Cmdlet that displays the output in a vertical list instead of a table.
-Property Parameter that specifies which properties to show.
* Wildcard character specifying that every available property and value should be displayed (including Path, InstanceName, CookedValue, RawValue, Timestamp, and Status).

When to use the script:

Admins can use this script to investigate metric anomalies, verify the health of Performance Data Helper (PDH) providers, or identify the properties available for use in automation scripts. By displaying the underlying object properties and diagnostic metadata, the script helps admins check whether a counter is returning valid measurements and identify details such as its status, instance name, and timestamp. It also reveals the exact property names needed to extract specific metric values in custom scripts.

Screenshot of the Hexnode UEM portal showing the output window of script to display an object’s property value using the Execute Custom Script remote action under the Manage tab.

Retrieve performance data for a specific processor instance

9.Retrieve performance data for a specific processor instance

Execute the following PowerShell script through Hexnode UEM to retrieve the processor usage reading for a specific logical processor instance on the target Windows device.

Syntax:

How the script works:

Component Function
\Processor(<Instance_Number>)\% Processor Time Counter path that specifies the logical processor instance whose CPU usage data is to be retrieved. Replace <
Instance_Number>
with an available processor instance number on the target device (e.g., 0, 1, 2 etc.).
$Counter Variable that stores the performance counter reading returned by Get-Counter.
$Counter.CounterSamples[0] Property that retrieves the first sample from the CounterSamples array. Since the query targets only one processor instance, it returns the reading for that instance.

When to use the script:

Administrators can use this script when they need to monitor CPU usage for a particular logical processor instance instead of retrieving readings for all processor instances on the device. This helps admins to inspect individual processor usage without collecting unnecessary counter data.

Example:

The following script retrieves CPU usage data for logical processor instance 0 on the target Windows device:

Screenshot of the Hexnode UEM portal showing the output window of script to retrieve performance data for a specific processor instance using the Execute Custom Script remote action under the Manage tab.

Notes:


Available processor instance numbers vary depending on the target device’s CPU configuration. Specifying an instance number that does not exist on the device results in an invalid counter path error.

Filter CPU usage readings by threshold

10. Filter CPU usage readings by threshold

Execute the following PowerShell script through Hexnode UEM to filter processor instances operating below a defined utilisation threshold.

The example below displays CPU instances running below a 20% threshold:

How the script works:

Component Function
“\Processor(*)\% Processor Time” Counter path that measures processor usage across all logical processor instances and the total system aggregate (_Total).
$Counter Variable that stores the query results across all processor units.
$Counter.CounterSamples Property that extracts the individual readings for each processor into a list.
Where-Object Cmdlet that filters the list based on your comparison rule.
$_.CookedValue Property that checks the calculated CPU percentage for each processor unit.
-lt Comparison operator (meaning “less than”) that compares each processor’s CPU percentage against the specified limit and only outputs readings that fall below it.This can be replaced with -gt (greater than) to filter for high usage.
20 Threshold limit that filters out any core working above 20%. This can be replaced with any value (e.g., 50 or 80).

When to use the script:

Admins can deploy this script to audit CPU workload distribution and identify underutilized logical processor instances. Filtering for processor instances operating below a specified threshold, such as 20%, helps admins detect uneven workload distribution or determine whether available processing capacity is being utilized effectively, without manually reviewing every counter reading.

Screenshot of the Hexnode UEM portal showing the output window of script to filter CPU usage by threshold using the Execute Custom Script remote action under the Manage tab.

Sort performance counter data

11. Sort performance counter data

Execute the following PowerShell script through Hexnode UEM to check current CPU usage across all running processes and organize the results from highest to lowest.

How the script works:

Component Function
“\Process(*)\% Processor Time” Counter path that collects CPU usage readings for all process instances, including individual processes, the system aggregate (_Total), and unused CPU cycles (Idle).
$Procs Variable that saves the collected process performance readings.
$Procs.CounterSamples Property that extracts the individual readings for each process into a list.
Sort-Object Cmdlet that organizes the list of process readings based on specified property values.
CookedValue Property that contains the calculated CPU usage value for each process instance and is used as the sorting criterion.
-Descending Parameter that directs the list to be sorted from highest value to lowest value.
Format-Table Cmdlet that arranges the output into clean columns.
-Property Parameter that specifies the object properties (Path, InstanceName, and CookedValue) to display in the output.
Path Column displaying the full performance counter path for the process.
InstanceName Column displaying the process name.
-AutoSize Parameter that adjusts column widths to fit the length of the text, preventing long names from being truncated.
Out-String Cmdlet that converts the formatted table output into plain text strings.
-Width Parameter that sets the line width to prevent long process paths and columns from wrapping or getting truncated in the script output displayed under Action History Log in Hexnode UEM.
300 Value that widens the text display area to 300 characters. This can be adjusted as needed.

When to use the script:

Admins can run this script to quickly identify which applications or background services are consuming the most processor power. Instead of scrolling through hundreds of unsorted processes, sorting the list from highest to lowest places the heaviest CPU consumers right at the top, making it easy to spot resource-draining software or troubleshoot performance slow-downs.

Screenshot of the Hexnode UEM portal showing the output window of script to sort performance counter data using the Execute Custom Script remote action under the Manage tab.

Frequently Asked Questions

Does executing Get-Counter scripts noticeably affect endpoint performance?

Standard queries and single readings take minimal system resources. Only high-frequency continuous sampling (e.g., collecting samples every second for long durations) generates noticeable CPU or disk overhead.

What happens if a device is offline when the script is deployed from Hexnode UEM?

The script action will remain in a “Pending” state in the Hexnode UEM portal. As soon as the Windows device reconnects to the internet and syncs with Hexnode, the Hexnode agent will automatically execute the script and upload the output to the portal.

Can performance counter scripts be set up to run automatically on a recurring schedule in Hexnode UEM?

Recurring script execution is supported through Automation by creating a time-triggered automation (such as daily or weekly) paired with the Execute Custom Script action for targeted Windows devices or device groups.

Why are some performance counters unavailable or returning errors on Windows devices?

Performance counter availability and query results can vary depending on the Windows configuration. Common reasons include:

  • OS Edition & Role Differences: Specialized counter sets (such as Hyper-V or IIS counters) exist only on devices with those specific Windows features or server roles installed.
  • Corrupted Performance Registry: Windows performance counter registries can occasionally become corrupted. Rebuilding the registry via lodctr /R on the endpoint resolves missing system counter paths.
  • System Language/Localization: Non-English Windows installations may fail to recognize standard English counter paths if localized path names are expected by the OS.
How to inspect specific counter paths within a set without loading all system counters?

Running Get-Counter -ListSet * queries every performance counter category on the target endpoint, which can increase the time taken by the script to return the results. To view paths for a single category (e.g., Processor or Memory), specify the category name directly:

(Get-Counter -ListSet "Processor").PathsWithInstances 
Sample Script Repository