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.
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
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.