Skip to main content

How to List Processes by CPU Usage in a Batch Script

When a computer is running slowly, the first step in diagnosing the problem is often to find out which process is consuming the most CPU resources. While the graphical Task Manager is great for interactive use, a batch script needs a command-line tool to get this information for logging, monitoring, or automated alerts.

This guide will teach you the modern, standard method for getting a list of processes sorted by their CPU usage using the powerful WMIC (Windows Management Instrumentation) command. You will learn the correct query to use and how WMIC's underlying properties can be used to approximate CPU load.

The Challenge: No Simple "Top" Command

Unlike Linux, which has the top command, Windows cmd.exe has no built-in, real-time utility that sorts processes by live CPU usage. The standard tasklist command can show memory usage but not CPU, and it cannot sort its output. Therefore, we must turn to a more powerful tool.

The Core Method: WMIC and Kernel/User Time

The WMIC (Windows Management Instrumentation Command-line) utility can query the total amount of processor time (in tiny 100-nanosecond units) that a process has consumed since it started. This is broken into two properties:

  • KernelModeTime: Time the process spent running in the privileged kernel mode.
  • UserModeTime: Time the process spent running in the less-privileged user mode.

The total CPU time is the sum of these two values. By getting a list of all processes and their total CPU time, we can get an excellent snapshot of which processes have been the most demanding over their lifetime.

note

This is a measure of cumulative CPU usage, not a real-time "instantaneous" percentage. For most diagnostic scripts, this is a very effective and reliable proxy.

The Unreliable Legacy Method (To Avoid): Parsing tasklist

Some older methods suggest using tasklist /v and trying to parse the "CPU Time" column.

Why this is not recommended:

  • It cannot be sorted. The tasklist command has no sort option.
  • The time format is difficult to parse. It is in HH:MM:SS format, which is not machine-readable for sorting or comparison in a batch script.
  • It is slow and verbose.

The WMIC method provides clean, numerical data that is far superior for scripting.

Example: Script to Get a List of Processes by CPU Load

This script uses WMIC to get the necessary properties. Because WMIC cannot perform the addition and sorting itself, we must pass its output to the SORT command.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

ECHO --- Listing Processes by Cumulative CPU Usage ---
ECHO This may take a moment to calculate...
ECHO.
ECHO CPU_Time (s) PID Process_Name
ECHO ============ ====== =============

REM Get the header for the CSV output of WMIC
FOR /F "tokens=*" %%H IN ('wmic process get KernelModeTime^,UserModeTime^,ProcessID^,Name /FORMAT:CSV 2^>NUL ^| find "Node"') DO (
SET "header=%%H"
)

REM Use a FOR /F loop to process the WMIC output
(
FOR /F "skip=1 tokens=1-4 delims=," %%A IN ('wmic process get KernelModeTime^,UserModeTime^,ProcessID^,Name /FORMAT:CSV 2^>NUL') DO (
SET /A "TotalTime=%%A + %%B"
SET /A "TotalTimeSecs=!TotalTime! / 10000000"

REM Pad the time for clean alignment
SET "PaddedTime= !TotalTimeSecs!"
SET "PaddedTime=!PaddedTime:~-12!"

SET "PaddedPID= %%C"
SET "PaddedPID=!PaddedPID:~-6!"

ECHO !PaddedTime! !PaddedPID! %%D
)
) | SORT /R

ENDLOCAL

How the WMIC Script Works

  • wmic process get ... /FORMAT:CSV: This is the core command. It gets the required properties in a clean, comma-separated format that is easy to parse.
  • skip=1 tokens=1-4 delims=,: The FOR /F loop processes this CSV data. It skips the header and splits each line into four tokens (variables %%A through %%D).
  • SET /A "TotalTime=%%A + %%B": This is the key calculation. It adds the Kernel and User mode times together to get the total CPU time.
  • SET /A "TotalTimeSecs=!TotalTime! / 10000000": The time is in 100-nanosecond units. This line converts it to whole seconds for readability.
  • | SORT /R: The entire output of the FOR loop (our custom-formatted lines) is piped to the SORT command. The /R switch sorts the results in Reverse (descending) order, putting the processes with the highest CPU time at the top.

A Note on PowerShell for a More Accurate, Real-Time View

The WMIC method gives a cumulative total. For a true, real-time, sorted list like the one in Task Manager, PowerShell is the only built-in tool that can do it effectively.

PowerShell One-Liner: powershell "Get-Process | Sort-Object -Descending CPU | Select-Object -First 10" This command gets all processes, sorts them by their current CPU usage (descending), and shows the top 10. For any serious real-time monitoring, this is the superior method.

Common Pitfalls and How to Solve Them

  • Administrator Rights: A standard user can only see their own processes. To get a complete list of all processes on the system (including system services that are often CPU-intensive), you must run the script as an Administrator.

  • 32-bit Math Limit: SET /A is limited to 32-bit signed integers. For a very long-running process, the total CPU time in 100-nanosecond units could exceed this limit, causing an overflow. Solution: For long-term server monitoring, the PowerShell method is more robust.

  • Script is Slow: The WMIC query can be slow, especially on a system with hundreds of processes. Solution: This is unavoidable. WMIC needs to gather a lot of data.

Practical Example: A "Top 10 CPU Hogs" Report

This script adapts the core logic to create a clean report showing only the top 10 most CPU-intensive processes over their lifetime.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

ECHO --- Top 10 CPU Consuming Processes (Cumulative) ---
ECHO.
SET "count=0"

(
FOR /F "skip=1 tokens=1-4 delims=," %%A IN ('wmic process get KernelModeTime^,UserModeTime^,ProcessID^,Name /FORMAT:CSV 2^>NUL') DO (
SET /A "TotalTime=%%A + %%B"
ECHO !TotalTime!,%%C,%%D
)
) | SORT /R > "%TEMP%\cpu_usage.tmp"

ECHO CPU_Time(ns),PID,Name
ECHO ===========================
FOR /F "tokens=*" %%L IN ('TYPE "%TEMP%\cpu_usage.tmp"') DO (
SET /A "count+=1"
IF !count! LEQ 10 ECHO %%L
)

DEL "%TEMP%\cpu_usage.tmp"
ENDLOCAL

Conclusion

While batch scripting has no direct way to sort processes by live CPU usage, the WMIC PROCESS command provides a powerful and effective method for listing processes by their cumulative CPU time.

  • The core method is to query WMIC PROCESS GET KernelModeTime,UserModeTime,....
  • You must perform the addition and any unit conversion yourself using SET /A.
  • The final step is to pipe the formatted output to SORT /R to get the highest consumers at the top.
  • For a true real-time sorted list, you must use PowerShell.