Skip to main content

How to Monitor Network Bandwidth Usage in Batch Script

Network bandwidth is a finite resource. If a computer is suddenly using 100% of its capacity, it could mean a massive backup is running, a user is streaming high-definition video, or a malicious process is exfiltrating data. While the Task Manager provides a nice graph, a Batch script can monitor the specific "Bytes Per Second" of your network card programmatically. By querying performance counters via typeperf or wmic, you can create an automated "Bandwidth Guard" that alerts you when usage exceeds a specific threshold.

This guide will explain how to track real-time bandwidth metrics.

Method 1: The "Real-Time Counter" (Typeperf)

typeperf is a powerful, often overlooked tool that can read Windows Performance Counters directly.

@echo off
setlocal

:: Use Typeperf to get 'Bytes Total/sec' for the current network card
:: Note: The counter name must match exactly.
:: To list available interfaces: typeperf -qx | findstr "Network Interface"

echo [MONITOR] Watching real-time network traffic...
echo Sampling every 2 seconds, 10 samples total.
echo Press CTRL+C to stop early.
echo.

:: Check if typeperf is available
where typeperf >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] typeperf is not available on this system. Use Method 2 or 3 instead.
pause
endlocal
exit /b 1
)

:: -si 2 = Sample interval of 2 seconds
:: -sc 10 = Sample count of 10
typeperf "\Network Interface(*)\Bytes Total/sec" -si 2 -sc 10

echo.
echo [DONE] Monitoring complete.

pause
endlocal

Identifying your interface: If you have multiple network cards (Wi-Fi and Ethernet), the (*) wildcard shows all of them. To target a specific adapter, first list the available names:

typeperf -qx | findstr "Network Interface"

Then replace (*) with the exact name, e.g., (Intel[R] Ethernet Connection I219-V). Note that special characters like parentheses in adapter names must match exactly.

Method 2: Calculating Throughput (WMIC)

If you don't have typeperf, you can query the Win32_PerfFormattedData_Tcpip_NetworkInterface class.

warning

WMIC has been deprecated starting in Windows 11. See Method 3 for a forward-compatible PowerShell alternative.

@echo off
setlocal enabledelayedexpansion

echo [QUERY] Monitoring Bandwidth Throughput...
echo Press CTRL+C to stop.
echo.

set "SampleCount=0"
set "MaxSamples=10"

:Loop
:: Prevent infinite loop - stop after MaxSamples
set /a SampleCount+=1
if !SampleCount! gtr %MaxSamples% (
echo.
echo [DONE] Collected %MaxSamples% samples.
goto :End
)

set "usage="

:: Nested FOR strips the invisible \r that WMIC output appends
for /f "skip=1 delims=" %%a in ('wmic path Win32_PerfFormattedData_Tcpip_NetworkInterface get BytesTotalPersec 2^>nul') do (
for /f "delims=" %%b in ("%%a") do (
if not defined usage set "usage=%%b"
)
)

:: Remove any leading/trailing spaces
if defined usage (
for /f "tokens=*" %%c in ("!usage!") do set "usage=%%c"
)

:: Validate the result
if not defined usage (
echo [%time%] ERROR: Could not read network counter.
) else (
echo [%time%] Sample !SampleCount!: !usage! Bytes/sec
)

timeout /t 2 >nul
goto :Loop

:End
pause
endlocal

Method 3: Calculating Megabytes Per Second (MB/s)

Raw "Bytes/sec" is hard to read. PowerShell's Get-Counter converts this into readable megabytes and adds threshold alerting.

@echo off
setlocal

echo [MONITOR] Real-time bandwidth in MB/s...
echo Sampling every 2 seconds, 10 samples.
echo.

:: -NoProfile speeds up PowerShell startup
:: Get-Counter replaces the deprecated Get-WmiObject approach
:: Threshold alert warns if traffic exceeds 50 MB/s
powershell -NoProfile -Command ^
"$threshold = 50;"^
"for ($i = 1; $i -le 10; $i++) {"^
" try {"^
" $sample = (Get-Counter '\Network Interface(*)\Bytes Total/sec' -ErrorAction Stop).CounterSamples;"^
" foreach ($s in $sample) {"^
" $mb = [math]::Round($s.CookedValue / 1MB, 2);"^
" $name = $s.InstanceName;"^
" $status = if ($mb -gt $threshold) { ' [!!! HIGH]' } else { '' };"^
" Write-Host ('{0:HH:mm:ss} | {1}: {2} MB/s{3}' -f (Get-Date), $name, $mb, $status);"^
" }"^
" } catch {"^
" Write-Host ('ERROR: ' + $_.Exception.Message);"^
" }"^
" if ($i -lt 10) { Start-Sleep -Seconds 2 }"^
"}"

echo.
echo [DONE] Monitoring complete.

pause
endlocal

Method 4: Logging to CSV for All-Day Monitoring

For tracking bandwidth over hours or days to identify peak usage times.

@echo off
setlocal

set "LogFile=%USERPROFILE%\bandwidth_log.csv"
set "Duration=3600"
set "Interval=5"

echo [MONITOR] Logging bandwidth to CSV...
echo File: %LogFile%
echo Duration: %Duration% seconds (%Interval%-second intervals)
echo.
echo Press CTRL+C to stop early.

:: typeperf natively supports CSV output
:: -si = sample interval in seconds
:: -sc = sample count (duration / interval)
set /a Samples=%Duration% / %Interval%

typeperf "\Network Interface(*)\Bytes Total/sec" ^
"\Network Interface(*)\Bytes Sent/sec" ^
"\Network Interface(*)\Bytes Received/sec" ^
-si %Interval% -sc %Samples% -f CSV -o "%LogFile%"

echo.
echo [DONE] Log saved to: %LogFile%

pause
endlocal
tip

Open the resulting CSV in Excel and create a chart to visualize traffic patterns. The separate Sent/Received counters help distinguish uploads from downloads.

How to Avoid Common Errors

Wrong Way: Using "Ping" to Test Bandwidth

"Ping" only tests latency (how fast the signal travels). It does not tell you how much data can fit through the "pipe."

Correct Way: Use performance counters (\Network Interface\Bytes Total/sec). They measure the actual volume of data flowing into and out of the machine.

Wrong Way: Creating an Infinite Loop Without an Exit Condition

A goto :Loop with no counter or exit mechanism will run forever, potentially filling up log files or consuming resources if left unattended.

Correct Way: Always include a sample counter or maximum duration:

set /a SampleCount+=1
if %SampleCount% gtr %MaxSamples% goto :End

Problem: Localized Counter Names

In non-English versions of Windows, the performance counter paths might be translated (e.g., \Netzwerkschnittstelle(*) in German).

Solution: Use WMIC (Method 2) or PowerShell's Get-Counter (Method 3), which use standardized class names regardless of the system language. Alternatively, find the localized counter names with:

typeperf -qx | findstr /i "network"

Problem: WMIC \r Carriage Return Corruption

WMIC output appends invisible carriage return characters (\r) to every value. Variables captured with a single FOR /F loop will contain trailing garbage that breaks numeric comparisons and display.

Solution: Use a nested FOR /F to strip the trailing characters:

for /f "skip=1 delims=" %%a in ('wmic ... 2^>nul') do (
for /f "delims=" %%b in ("%%a") do set "var=%%b"
)

Best Practices and Rules

1. Separate Send vs. Receive

If you are troubleshooting a slow connection, monitor Bytes Sent/sec and Bytes Received/sec separately. A high "Sent" count usually indicates an upload or data exfiltration, while high "Received" usually means a download or video stream:

typeperf "\Network Interface(*)\Bytes Sent/sec" "\Network Interface(*)\Bytes Received/sec" -si 2 -sc 10

2. Administrative Privileges

Querying real-time performance counters generally requires running as an Administrator. Without elevation, some counters may return zero or access-denied errors.

3. Log to CSV for Long-Term Monitoring

If you are tracking usage for a whole day to see when the "peak" happens, use Method 4 or redirect output to a CSV file:

typeperf "\Network Interface(*)\Bytes Total/sec" -si 5 -sc 720 -f CSV -o network_usage.csv

This captures 720 samples at 5-second intervals (1 hour of monitoring).

4. Set Threshold Alerts

Don't just passively log, actively alert when bandwidth exceeds acceptable levels. Method 3 demonstrates a basic threshold check. For production use, consider writing alerts to the Windows Event Log.

5. WMIC Deprecation

Microsoft has deprecated WMIC starting in Windows 11. For forward-compatible scripts, use PowerShell's Get-Counter (Method 3) or Get-CimInstance as replacements.

6. Always Use setlocal / endlocal

Without setlocal, every variable your script creates persists in the parent shell session, causing potential conflicts when running multiple scripts in sequence.

Conclusions

Monitoring network bandwidth usage provides a window into the health and security of your system's communication. By transforming raw performance data into actionable throughput metrics, you can identify resource-heavy applications and detect unusual network activity before it impacts your work. This proactive visibility is a cornerstone of professional system administration and network performance optimization.