How to check if ping responded or not in a batch file - command-line

I want to continuously ping a server and see a message box when ever it responds i.e. server is currently down. I want to do it through batch file.
I can show a message box as said here Show a popup/message box from a Windows batch file
and can ping continuously by
ping <servername> -t
But how do I check if it responded or not?

The question was to see if ping responded which this script does.
However this will not work if you get the Host Unreachable message as this returns ERRORLEVEL 0 and passes the check for Received = 1 used in this script, returning Link is UP from the script. Host Unreachable occurs when ping was delivered to target notwork but remote host cannot be found.
If I recall the correct way to check if ping was successful is to look for the string 'TTL' using Find.
#echo off
cls
set ip=%1
ping -n 1 %ip% | find "TTL"
if not errorlevel 1 set error=win
if errorlevel 1 set error=fail
cls
echo Result: %error%
This wont work with IPv6 networks because ping will not list TTL when receiving reply from IPv6 address.

The following checklink.cmd program is a good place to start. It relies on the fact that you can do a single-shot ping and that, if successful, the output will contain the line:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
By extracting tokens 5 and 7 and checking they're respectively "Received" and "1,", you can detect the success.
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=%1
:loop
set state=down
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%b"=="xunreachable." goto :endloop
if "x%%a"=="xReceived" if "x%%c"=="x1," set state=up
)
:endloop
echo.Link is !state!
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
Call it with the name (or IP address) you want to test:
checklink 127.0.0.1
checklink localhost
checklink nosuchaddress
Take into account that, if your locale is not English, you must replace Received with the corresponding keyword in your locale, for example recibidos for Spanish. Do a test ping to discover what keyword is used in your locale.
To only notify you when the state changes, you can use:
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
if not !state!==!oldstate! (
echo.Link is !state!
set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
However, as Gabe points out in a comment, you can just use ERRORLEVEL so the equivalent of that second script above becomes:
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
if not !state!==!oldstate! (
echo.Link is !state!
set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

I know this is an old thread, but I wanted to test if a machine was up on my system and unless I have misunderstood, none of the above works if my router reports that an address is unreachable. I am using a batch file rather than a script because I wanted to "KISS" on pretty much any WIN machine. So the approach I used was to do more than one ping and test for "Lost = 0" as follows
ping -n 2 %pingAddr% | find /I "Lost = 0"
if %errorlevel% == 0 goto OK
I haven't tested this rigorously but so far it does the job for me

I have made a variant solution based on paxdiablo's post
Place the following code in Waitlink.cmd
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=%1
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
echo.Link is !state!
if "!state!"=="up" (
goto :endloop
)
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
:endloop
endlocal
For example use it from another batch file like this
call Waitlink someurl.com
net use o: \\someurl.com\myshare
The call to waitlink will only return when a ping was succesful. Thanks to paxdiablo and Gabe. Hope this helps someone else.

Here's something I found:
:pingtheserver
ping %input% | find "Reply" > nul
if not errorlevel 1 (
echo server is online, up and running.
) else (
echo host has been taken down wait 3 seconds to refresh
ping 1.1.1.1 -n 1 -w 3000 >NUL
goto :pingtheserver
)
Note that ping 1.1.1.1 -n -w 1000 >NUL will wait 1 second but only works when connected to a network

thanks to #paxdiablo and #Jan Lauridsen
this is my modification to check and IP (local machine), good for case which connection is dropped either from dhcp server or any other issue, tested Under WinXP PRO SP3
checkconnection.cmd:
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=8.8.8.8
:loop
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%b"=="xunreachable." goto :endloop
if "x%%b"=="xtimed out." goto :endloop
if "x%%a"=="xReceived" if "x%%c"=="x1," goto :up
)
:endloop
set state=Down
echo.Connection is !state!
ping -n 2 127.0.0.1 >nul: 2>nul:
echo starting Repairing at %date% %time%>>D:\connection.log
call repair.cmd>>D:\connection.log
ping -n 10 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
:up
set state=Up
echo.Connection is !state!
ping -n 6 127.0.0.1 >nul: 2>nul:
cls
goto :loop
endlocal
if no ping response from google DNS then start repair, i had static IP set for this purpose but it should work with dinamic as well.
repair.cmd:
route -f
ipconfig /release
ipconfig /renew
arp -d *
nbtstat -R
nbtstat -RR
ipconfig /flushdns
ipconfig /registerdns
cls
My Best Regards

You can ping without "-t" and check the exit code of the ping. It reports failure when there is no answer.

Simple version:
for /F "delims==, tokens=4" %a IN ('ping -n 2 127.0.0.1 ^| findstr /R "^Packets: Sent =.$"') DO (
if %a EQU 2 (
echo Success
) ELSE (
echo FAIL
)
)
But sometimes first ping just fail and second one work (or vice versa) right? So we want to get success when at least one ICMP reply has been returned successfully:
for /F "delims==, tokens=4" %a IN ('ping -n 2 192.168.1.1 ^| findstr /R "^Packets: Sent =.$"') DO (
if %a EQU 2 (
echo Success
) ELSE (
if %a EQU 1 (
echo Success
) ELSE (
echo FAIL
)
)
)

I hope this helps someone. I use this bit of logic to verify if network shares are responsive before checking the individual paths. It should handle DNS names and IP addresses
A valid path in the text file would be
\192.168.1.2\'folder' or \NAS\'folder'
#echo off
title Network Folder Check
pushd "%~dp0"
:00
cls
for /f "delims=\\" %%A in (Files-to-Check.txt) do set Server=%%A
setlocal EnableDelayedExpansion
ping -n 1 %Server% | findstr TTL= >nul
if %errorlevel%==1 (
ping -n 1 %Server% | findstr "Reply from" | findstr "time" >nul
if !errorlevel!==1 (echo Network Asset %Server% Not Found & pause & goto EOF)
)
:EOF

I've modified PaxDiablo's code slightly to better fit with what I was doing and thought I'd share. My objective was to loop through a list of IP addresses to see if any were left on, and this code is to be run at the end of the last shift of the weekend to check if everyone is following the instructions to shut down all PCs before they go home.
Since using a goto in a for loop breaks out of all for loops not just the lowest nested for loop, PaxDiablo's code stopped processing further IP addresses when it got to one that was unreachable. I found that I could add a second variable to track that it was unreachable rather than exiting the loop and now this code is now running perfectly for me.
I have the file saved as CheckPCs.bat and though I'm guessing it's not proper coding practice, I do have the IP addresses listed below the code along with a description which in my case is the physical location of the PC. As mentioned by others you will have to modify the code further for other localizations and for IPV6.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (
set ipaddr=%%i
set state=shut down
set skip=0
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%b"=="xunreachable." set skip=1
if !skip!==0 if "x%%a"=="xReceived" if "x%%c"=="x1," set state=still on
)
echo %%i %%j is !state!
)
pause
endlocal
rem /IP ADDRESS0/COMPUTER NAME0
rem /IP ADDRESS1/COMPUTER NAME1
Some notes if you do need to modify this code:
for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (
The for loop is processing CheckPCs.bat one line at a time. Skip is telling it to ignore the first 16 lines and go straight to the IP addresses. I'm using / as a delimiter for no particular reason but note that if you are pinging web addresses instead of IP, you'll have to change the delimiter. Something like the pipe character | would work. Of course since the line is commented out with rem, rem becomes the first token which means I only want to work with tokens 2 and 3 which will be the IP address and PC description. The latter field is optional, you'd just have to modify the code to remove it.
You should probably modify the terminology used for state and for echo %%i %%j is !state! so that the terminology is clear and concise for you. If you want to record the state somewhere, you can just feed it into a text file by appending >> file.txt to the line. You might want to also add a date/time in that case.
Lastly, something people with proper training in coding these might know, the way a batch for loop with tokens works (in simple terms) is each section of the text is split up at each delimiter, the default being space, and then it is assigned to a %% variable whose name begins at whichever character you specify and then increases up the ascii character list. This means if I specify to start at %%i, the next token will be %%j, then %%k and so on. If I used %%B, next would be %%C, then %%D etc. There can be a maximum of 31 tokens per another thread I read on the topic.

Following #Dan W answer:
#echo off
set Server=192.168.0.18
setlocal EnableDelayedExpansion
:checkhost
ping -n 1 %Server% | findstr TTL= >nul
if %errorlevel%==1 (
ping -n 1 %Server% | findstr "Reply from" | findstr "time" >nul
if !errorlevel!==1 (echo Network Asset %Server% Not Found & goto checkhost)
)

I've seen three results to a ping - The one we "want" where the IP replies, "Host Unreachable" and "timed out" (not sure of exact wording).
The first two return ERRORLEVEL of 0.
Timeout returns ERRORLEVEL of 1.
Are the other results and error levels that might be returned? (Besides using an invalid switch which returns the allowable switches and an errorlevel of 1.)
Apparently Host Unreachable can use one of the previously posted methods (although it's hard to figure out when someone replies which case they're writing code for) but does the timeout get returned in a similar manner that it can be parsed?
In general, how does one know what part of the results of the ping can be parsed? (Ie, why might Sent and/or Received and/or TTL be parseable, but not host unreachable?
Oh, and iSid, maybe there aren't many upvotes because the people that read this don't have enough points. So they get their question answered (or not) and leave.
I wasn't posting the above as an answer. It should have been a comment but I didn't see that choice.

#!/bin/bash
logPath="pinglog.txt"
while(true)
do
# refresh the timestamp before each ping attempt
theTime=$(date -Iseconds)
# refresh the ping variable
ping google.com -n 1
if [ $? -eq 0 ]
then
echo $theTime + '| connection is up' >> $logPath
else
echo $theTime + '| connection is down' >> $logPath
fi
Sleep 1
echo ' '
done

Related

How to stop counting of timeout automatically if command finishes earlier?

In my script I'm using timeout to set a maximum timelimit for executing a command.
start 7z.exe t %%f
if errorlevel 2 (DEL %%f & echo File broken. Reload File!)
timeout /t 3600
If the execution lasts longer than an hour the timeout should break the execution. That's working without any problems.
But how can I ignore the timeout counting and proceed my script automatically if the command finishes before the timestamp?
As curretly written, start command without /W switch does not affect/change errorlevel! Proof:
==> hfhgf
'hfhgf' is not recognized as an internal or external command,
operable program or batch file.
==> echo %errorlevel%
9009
==> start "" ping.exe localhost
==> echo %errorlevel%
9009
==> start "" /W ping.exe localhost
==> echo %errorlevel%
0
Use /W or /WAIT switch (start application and wait for it to terminate) and remove all that timeout line as follows. I guess that your code snippet could be do part of a for loop:
for %%f in (*.zip) do (
(call )
start "" /W 7z.exe t "%%f"
if errorlevel 2 (
echo File broken. Reload File %%f
DEL "%%f"
)
)
On (call ) explanation, see Dave Benham's reply to setting ERRORLEVEL to 0 question:
If you want to force the errorlevel to 0, then you can use this
totally non-intuitive, but very effective syntax: (call ). The space
after call is critical. If you want to set the errorlevel to 1, you
can use (call). It is critical that there not be any space after
call.

Pre-Commit Windows Hook to Require Issue Number in Comment

I am looking for a way to reject commits that lack a bug issue number in their comments. The system I am setting up uses VisualSVN Server on Windows Server 2012 and MantisBT on a LAMP server for bug tracking. This question has been asked before, but the repository in that case was on a LAMP server. I am looking for a batch or PowerShell script which does not depend on PHP or compiling code. Ideally, the hook would require "issue #1234" or "issues #12 and #34" to be present somewhere in the commit message.
Based on this batch file:
After this block:
setlocal enabledelayedexpansion
set REPOS=%1
set TXN=%2
set SVNLOOK="%VISUALSVN_SERVER%\bin\svnlook.exe"
REM Concatenate all the lines in the commit message
FOR /F "usebackq delims==" %%g IN (`%SVNLOOK% log -t %TXN% %REPOS%`) DO SET M=!M!%%g
add the check:
echo !M! | findstr /i /r /c:"issues* *#[0-9][0-9]*" >nul
if errorlevel 1 (
echo "Sorry, commit message should reference an issue" >&2
exit /b 1
)

Controlling Multiple command prompt through one main window

Does anyone knows how to control many command prompt windows through one . What exactly I would like to do is start many command windows and then run multiple commands in all of them through a batch file. Such as starting adb shell logcat in one, kmsg in one and if kmsg stops then turn red, and similar things.
For that I need to be able to listen to events from other command lines and also send commands to many command prompt one after the other.
Thanks your reply is appreciated.
If you know how to do it in perl that would also work. Plzz help!!
Updated;
Update Notes:
Took note of Jeb's suggestion and took his advice as well as Endoro's
Okay, this will be a little complicated because it needs batch files to write into some sort of file and another batch file getting / grabbing the data from said file. In order to do this, we must produce the "sender / terminal / MAIN window" for your batch file;
The script i am writing for you as of now can only support 4 Batch files being controlled by a mother batch file.
#echo off
:a
title Main Terminal
echo ---------------------------
set /p prompt1="Command 1: "
set /p prompt2="Command 1: "
set /p prompt3="Command 1: "
set /p prompt4="Command 1: "
if defined prompt echo %prompt% > com1.rsm
if defined prompt2 echo %prompt2% > com2.rsm
if defined prompt3 echo %prompt3% > com3.rsm
if defined prompt4 echo %prompt4% > com4.rsm
:: .RSM file extension means ReSource Module; I made it myself :3
goto a
Receiver
#echo off
title Reciever 1
:check
if EXIST com1.rsm goto get
timeout /t 1 >nul
echo Waiting for packet
goto check
:get
set /p prompt1=<com1.rsm
%prompt1%
del com1.rsm
goto check
Receiver 2
#echo off
title Reciever 2
:check
if EXIST com2.rsm goto get
timeout /t 1 >nul
echo Waiting for packet
goto check
:get
set /p prompt=<com2.rsm
%prompt%
del com1.rsm
goto check
Receiver 3
#echo off
title Reciever 3
:check
if EXIST com3.rsm goto get
timeout /t 1 >nul
echo Waiting for packet
goto check
:get
set /p prompt=<com3.rsm
%prompt%
del com1.rsm
goto check
Receiver 4
#echo off
title Reciever 4
:check
if EXIST com4.rsm goto get
timeout /t 1 >nul
echo Waiting for packet
goto check
:get
set /p prompt=<com4.rsm
%prompt%
del com1.rsm
goto check
You're welcome;
SonorousTwo

Batch file to restart a specific service based on the CPU of a process

I'm hoping you can help me with this, I've tried researching for hours but can't seem to get anywhere with it.
I have a process which randomly starts to consume 50+ CPU a few times a day, I'm trying to create a batch file which will run in the background and restart the service if the CPU usage of the process gets above 50 (fixes the issue).
I found something very close on this forum, a guy named "Elektro Hacker" answered, but his answer is the overall CPU usage, not just the usage of a specific process. Here is the batch file he suggested:
#Echo OFF
SET "SERVICE=Themes"
SET /A "MAXUSAGE=95"
SET /A "INTERVAL=5"
:LOOP
For /F %%P in ('wmic cpu get loadpercentage ^| FINDSTR "[0-9]"') do (
IF %%P GTR %MAXUSAGE% (
Echo [%TIME:~0,8%] CPU Usage: %%P%% Reached the limit: %MAXUSAGE%%%
Echo Restarting %SERVICE% ...
SC STOP "%SERVICE%" 1>NUL
SC START "%SERVICE%" 1>NUL
Echo Service restarted.
) ELSE (
Echo [%TIME:~0,8%] CPU Usage: %%P%%
)
)
Ping -n %INTERVAL% Localhost >NUL
GOTO :LOOP
He also put: "For more precission maybe you want to check the current CPU percentage of the executable associated to the service using:
wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessor
Time
This is the part I can't get past, I keep getting errors, and every time I try to fix it by changing it slightly, I get different errors!
Can anybody change this code slightly, to get it to get the CPU of say "MyProcess"
The process and service names are different, I'm not sure if this would make a difference but thought it was worth mentioning.
My coding knowledge is minimal at best, so any help or advice you could give me is greatly appreciated, this is driving my crazy!
Thanks a lot!
Powesshell can do better
get-process wmiprvse | select processname,cpu,id | ? {$_.cpu -gt 90 -and $_.id} | foreach { restart-service winmgmt }
Remove the space:
wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime
You could also do:
wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime | find "myprocess"
You need to use ^ to escape the comma from Name,PercentProcessorTime. It should look like:
For /F %%P in ('wmic path Win32_PerfFormattedData_PerfProc_Process get Name^,PercentProcessorTime ^| FINDSTR "[0-9]"') do (
But this is just correct in terms of syntax - findstr will match "ProcessName %Load", whereas the script wants to match only "%Load".
Unfortunately, I'm not proficient in Windows batch scripts and am neither looking for that, so I had to use a third party software called GAWK (gnu awk) to be able to output only the "%Load" part.
This is the script I am using:
NB1: SERVICE=ProcessName - without .exe!
NB2: I'm appending .exe with: "%SERVICE%".exe
NB3: I'm using taskkill instead of sc stop/start
#Echo OFF
SET "SERVICE=ProcessName"
SET /A "MAXUSAGE=95"
SET /A "INTERVAL=10"
:LOOP
For /F %%P in ('wmic path Win32_PerfFormattedData_PerfProc_Process get Name^,PercentProcessorTime ^| find "%SERVICE%" ^| "C:\Program Files\GnuWin32\bin\awk.exe" "{print $2}"') do (
IF %%P GTR %MAXUSAGE% (
Echo [%TIME:~0,8%] CPU Usage: %%P%% Reached the limit: %MAXUSAGE%%%
Echo Restarting %SERVICE% ...
taskkill /f /im "%SERVICE%".exe 1>NUL
Echo Service restarted.
) ELSE (
Echo [%TIME:~0,8%] CPU Usage: %%P%%
)
)
Ping -n %INTERVAL% Localhost >NUL
GOTO :LOOP

How do i monitor network traffic on Windows from the command line

How do i monitor network traffic on Windows from the command line; specifically the download/upload speeds and amount of data uploaded/downloaded ? Is there a script /batch for doing that ?
While tshark is really powerful if you want to have fine grained statistics (according to hosts, protocols, ...), it has the main drawback to gather statistics during the time period it is running. As such, it is only good at reporting "instant" statistics but not to report poll traffic at regular points in time to have a view of how your network traffic changes along the day, week, ...
Moreover, as tshark makes packets capturing, there is some overhead.
So, according to your needs, you might be interested in the MS Windows net or netstat commands (netstat has option to report statistics by protocol). 'net statistics [Server|workstation]' or 'netstat [-e|-s]' are, as far as network traffic statistics are concerned, the MS Windows equivalents of Linux 'ifconfig' (or 'cat /proc/net/dev' if you prefer).
Note that, as ifconfig do, net or netstat only report amount of data since the interface has been brought up.
In order to obtain traffic rates, you've got to timestamp your calls to those commands and do the computation yourself.
AFAIK, both commands are shipped with all recent MS Windows versions.
I'm updating the answer for a more complete an accurate one, using netsh command, and some string operations to avoid Windows 32bits integer overflow.
Remember you need to run netsh interface ip show subinterfaces and check what is the line of your network adapter. The following batch file uses the 4th string line, that's the 1st adapter listed.
It checks the speed every 10 seconds. If your upload or download speed is up to 100 MBytes per seconds, you need to repeat the loop more often (for example every 1 second).
It creates a .csv file too. Remove that last line if you don't need it.
The batch file:
#ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION
set TAB=
echo Timestamp%TAB%Down bytes%TAB%Up bytes%TAB%Down speed%TAB%Up speed
:looptask
:: Store console command result
SET count=1
::FOR /F "tokens=* USEBACKQ" %%F IN (`netstat -e`) DO (
FOR /F "tokens=* USEBACKQ" %%F IN (`netsh interface ip show subinterfaces`) DO (
SET string!count!=%%F
SET /a count=!count!+1
)
:: *** Change string number to the line with your interface data ***
set line=%string4%
:: For ME, bytes transfered line is string3 using netstat and string4 using netsh
:: Get rid of the whitespaces
:loopreplace
if defined line (
set "new=!line: = !"
if "!new!" neq "!line!" (
set "line=!new!"
goto :loopreplace
)
)
if defined line if "!line:~0,1!" equ " " set "line=!line:~1!"
if defined line if "!line:~-1!" equ " " set "line=!line:~0,-1!"
:: Extracting bytes downloaded and uploaded
::FOR /F "tokens=2,3 delims= " %%A IN ("%line%") DO (
FOR /F "tokens=3,4 delims= " %%A IN ("%line%") DO (
set dbytes=%%~A
set ubytes=%%~B
)
:: Midnight epoch
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set time=%ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~8,2%") DO SET /A hs=%%A+0
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~10,2%") DO SET /A min=%%A+0
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~12,2%") DO SET /A sec=%%A+0
set /a epoch=%hs%*3600+%min%*60+%sec%
:: Calc initial transfer
if not defined LOOPCOMPLETE (
echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%0.00 KB/s%TAB%0.00 KB/s
goto :skip
)
:: Read .CSV file last line values
for /f %%i in ('find /v /c "" ^< bwlog.csv') do set /a lines=%%i
set /a lastLine=%lines% - 1
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`more /e +%lastLine% bwlog.csv`) DO (
SET string!count!=%%F
SET /a count=!count!+1
)
FOR /F "tokens=1,2,3 delims=," %%A IN ("%string1%") DO (
set lasttime=%%~A
set lastdown=%%~B
set lastup=%%~C
)
if %epoch% == %lasttime% (
goto :skip
)
:: 2,147,483,647 is the maximum value of a integer you can use, so only keep 9 characters
set /a lastup=%lastup: =%
set /a ddif=%dbytes:~-9% - %lastdown:~-9%
set /a udif=%ubytes:~-9% - %lastup:~-9%
:: Calc bandwidth
set /a dspeed=(ddif)/(epoch-lasttime)/10
set ddec=%dspeed:~-2%
set /a dspeed=(ddif)/(epoch-lasttime)/1000
set /a uspeed=(udif)/(epoch-lasttime)/10
set udec=%uspeed:~-2%
set /a uspeed=(udif)/(epoch-lasttime)/1000
echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%%dspeed%.%ddec% KB/s%TAB%%uspeed%.%udec% KB/s
:skip
:: Append the .CSV file
echo %epoch%,%dbytes%,%ubytes% >> "bwlog.csv"
:: Do every 10 seconds
set LOOPCOMPLETE=1
timeout /t 10 /nobreak >nul
goto :looptask
ENDLOCAL
Keep in touch if you need a fix.
Previous solution using a batch file, with some limitations:
I wanted to give you an easier solution, then I used my previous answer to code a fresh windows batch script that iterates every 10 seconds. It monitors download and upload bandwidth/speed in console and logs ammount of bytes transferred in a .csv file.
#ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION
set TAB=
echo Timestamp%TAB%Down bytes%TAB%Up bytes%TAB%Down speed%TAB%Up speed
:: Store console command result
:looptask
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`netstat -e`) DO (
SET string!count!=%%F
SET /a count=!count!+1
)
:: Bytes transfered line is string3
:: Get rid of the whitespaces
:loopreplace
if defined string3 (
set "new=!string3: = !"
if "!new!" neq "!string3!" (
set "string3=!new!"
goto :loopreplace
)
)
if defined string3 if "!string3:~0,1!" equ " " set "string3=!string3:~1!"
if defined string3 if "!string3:~-1!" equ " " set "string3=!string3:~0,-1!"
:: Extracting bytes downloaded and uploaded
set line=%string3:~6%
FOR /F "tokens=1,2 delims= " %%A IN ("%line%") DO (
set dbytes=%%~A
set ubytes=%%~B
)
:: Midnight epoch
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set time=%ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~8,2%") DO SET /A hs=%%A+0
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~10,2%") DO SET /A min=%%A+0
FOR /F "tokens=* delims=0" %%A IN ("%ldt:~12,2%") DO SET /A sec=%%A+0
set /a epoch=%hs%*3600+%min%*60+%sec%
:: Calc speeds
if not defined LOOPCOMPLETE (
echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%0.00 KB/s%TAB%0.00 KB/s
goto :skip
)
:: Read .CSV file last line values
for /f %%i in ('find /v /c "" ^< bwlog.csv') do set /a lines=%%i
set /a lastLine=%lines% - 1
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`more /e +%lastLine% bwlog.csv`) DO (
SET string!count!=%%F
SET /a count=!count!+1
)
FOR /F "tokens=1,2,3 delims=," %%A IN ("%string1%") DO (
set lasttime=%%~A
set lastdown=%%~B
set lastup=%%~C
)
if %epoch% == %lasttime% (
goto :skip
)
set /a dspeed=(dbytes-lastdown)/(epoch-lasttime)/10
set ddec=%dspeed:~-2%
set /a dspeed=(dbytes-lastdown)/(epoch-lasttime)/1000
set /a uspeed=(ubytes-lastup)/(epoch-lasttime)/10
set udec=%dspeed:~-2%
set /a uspeed=(ubytes-lastup)/(epoch-lasttime)/1000
echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%%dspeed%.%ddec% KB/s%TAB%%uspeed%.%udec% KB/s
:skip
:: Append the .CSV file
echo %epoch%,%dbytes%,%ubytes% >> "bwlog.csv"
:: Do every 10 seconds
set LOOPCOMPLETE=1
timeout /t 10 /nobreak >nul
goto :looptask
ENDLOCAL
PS: Windows limitations are the counter resets every 4GBytes transferred and at midnight.
Old solution using task scheduller and XAMPP:
I had to monitor and log the amount of data downloaded as your case, and found it faster to run a script with the Windows task scheduller than looking for a free software that dump the usual graphics info into a file. Perhaps my homemade script works for you.
I started a local Apache/PHP server using XAMPP for Windows and run this script from command line. For example:
"C:\xampp\php\php.exe -f C:\xampp\htdocs\bwlog.php"
The bwlog.php script uses #phep answer suggested windows command netstat -e. You can create the script file with the notepad, and the code is:
<?php
//Task to schedule "C:\xampp\php\php.exe -f C:\xampp\htdocs\bwlog.php"
//Store console command result
$netstat=shell_exec("netstat -e");
//Start of the bytes transfered line
$line=substr($netstat,strpos($netstat,"Bytes"));
//End of the line
$line=substr($line,0,strpos($line,"\n"));
//Get rid of the whitespaces
$bytes=preg_replace('/\s+/', ' ',$line);
//Extracting only bytes downloaded
$bytes=substr($bytes,$start=strpos($bytes,' ')+1,strrpos($bytes,' ')-$start);
//Append the .CSV file
file_put_contents('C:\xampp\htdocs\bwlog.csv',PHP_EOL.time().', '.$bytes,FILE_APPEND);
?>
Then I processed the the .csv in a spreadsheet software to calc the download speed (bandwidth) using the difference between 2 bytes values over the difference between the 2 matching time values (bytes/seconds).
Feel free to ask a fix to log the uploaded bytes. Wish it be useful.
You can use tshark with -z <statistics> argument. Just search Wireshark. It is open source and multiplatform.
typeperf in Windows should work to get the data.
typeperf "\Network Interface(*)\....
typeperf -q "Network Interface" will list all the object
\Network Interface(*)\Bytes Total/sec
\Network Interface(*)\Packets/sec
\Network Interface(*)\Packets Received/sec
\Network Interface(*)\Packets Sent/sec
\Network Interface(*)\Current Bandwidth
\Network Interface(*)\Bytes Received/sec
\Network Interface(*)\Packets Received Unicast/sec
\Network Interface(*)\Packets Received Non-Unicast/sec
\Network Interface(*)\Packets Received Discarded
\Network Interface(*)\Packets Received Errors
\Network Interface(*)\Packets Received Unknown
\Network Interface(*)\Bytes Sent/sec
\Network Interface(*)\Packets Sent Unicast/sec
\Network Interface(*)\Packets Sent Non-Unicast/sec
\Network Interface(*)\Packets Outbound Discarded
\Network Interface(*)\Packets Outbound Errors
\Network Interface(*)\Output Queue Length
\Network Interface(*)\Offloaded Connections