Need to run a command when I get a ping response - cmd

The idea is that a new device enters my network and a script running in the background can run a command to back it up, SyncToy for example (cd Program Files/SyncToy SyncToyCmd.exe -r).
I've run into scripts from similiar questions (How to check if ping responded or not in a batch file)
#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 I can't figure out how to run the command when the state changes to "up" as an exception in the loop, I also only want to run it once, adding a condition of once every 12 hours maybe.

Is this as simple as placing the command inside the block that tests for receipt? I do not understand how SyncToy would know the IP address.
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%a"=="xReceived" if "x%%b"=="x1," (
set state=up
PUSHD "%ProgramFiles%/SyncToy"
SyncToyCmd.exe -r
POPD
)
)

Related

psexec is not recognized as an internal or external command while running a batch file from windows scheduler

I have a .bat file to start the Windows service. When I run it manually it works fine but if I run it from task scheduler it gives the following error.
'psexec64.exe' is not recognized as an internal or external command,
operable program or batch file.
The system cannot find the file sessid.txt.
Press any key to continue . . .
I tried with the following scenarios
Tried with both psexec64.exe and psexec.exe
Added the psexec path in environment variables
still no luck
#echo off
setlocal enabledelayedexpansion
set username=user1
set usr=bdomain\user1
set password=2018
set machine=192.168.1.16
psexec64.exe \\%machine% -u %usr% -p %password% query session %username%>D:\Service_Start\sessid.txt
set /a counter=0
for /F "tokens=* skip=1" %%a in (sessid.txt) do (
for %%b in (%%a) do (
set /a counter+=1
if !counter! == 3 (
psexec64.exe \\192.168.1.16 -u bdomain\user1 -p 2018 -i %%b -d net start OracleServiceTest
)
)
)
pause;
modified the code as below and it's working
setlocal enabledelayedexpansion
set username=user1
set usr=bdomain\user1
set password=2018
set machine=192.168.1.16
D:\PSTools\psexec64.exe \\%machine% -u %usr% -p %password% query session %username%>D:\Service_Start\sessid.txt
set /a counter=0
for /F "tokens=* skip=1" %%a in (D:\Service_Start\sessid.txt) do (
for %%b in (%%a) do (
set /a counter+=1
if !counter! == 3 (
D:\PSTools\psexec64.exe \\192.168.1.16 -u bdomain\user1 -p 2018 -i %%b -d net start OracleServiceTest
)
)
)

Pinging to multiple servers via windows batch script

I'm trying to check response from list of n-thousand IPs using ping command via windows batch script and save all results in a file (yes if response and no if don't). Is this even possible via batch script? When I'm using script printed below (pingingN.bat) I'm getting only first IP answer.
#ECHO OFF
SET ServerList="C:\MyPath\ip.txt"
SET LogFile="C:\MyPath\PingResults.txt"
IF EXISTS %LogFile% DEL %LogFile%
FOR %%a IN (%ServerList%) DO (
ping -n 1 %%a | find "TTL=" > NUL
IF %ERRORLEVEL% NEQ 0 (
echo no >> %LogFile%
) ELSE (
echo yes >> %LogFile%
)
)
Based on my comment and using the && and || conditionals, here's how I would do it:
#Echo Off
Set "ServerList=C:\MyPath\ip.txt"
Set "LogFile=C:\MyPath\PingResults.txt"
If Not Exist "%ServerList%" Exit /B
>"%LogFile%" (For /F UseBackQ %%A In ("%ServerList%"
) Do Ping -n 1 %%A|Find "TTL=">Nul&&(Echo Yes [%%A])||Echo No [%%A])
You'll note that I have also included the IP in the output, otherwise your log file will not show you which ones did or didn't pass/fail.
you can use delayed Expansion or if errorlevel (as commented by aschipfl) or use another approach:
(FOR %%a IN (%ServerList%) DO (
ping -n 1 %%a | find "TTL=" > NUL && (
echo %%a, yes
) || (
echo %%a, no
)
)>%LogFile%
where && means "if previous command (find) was successful then" and || "if previous command (find) failed then"
Just redirecting once the whole output instead of each line on it's own gives you a big speed boost.
Create a file (test.txt) and list down all the IPs you want to ping.
Create another bat.file and write this command.
(for /F %i in (test.txt) do ping -n 1 %i 1>nul && echo %i UP || echo %i DOWN ) 1>result.txt
Run this command, It will list down which IP is up and which one is down.

Batch file 'continue' to next iteration in FOR loop

I'm currently supporting a team of techs who are upgrading machines in offices and I need to keep track of the amount of machines that are online.
Currently what I have is a text file (OfficeName.txt) with a list of machine names, and a batch file (OfficeName.bat).
What I want to happen is for it to loop through the list of machines and ping them.
If the ping is successful, remove the name from the list and increment a counter by 1, if unsuccessful, then move on to the next machine in the list.
The issue I'm having is that if a machine's ping result comes back with "could not find host", it still sets the errorlevel to 0, so I can't use an IF/ELSE.
My current attempt looks like this:
#echo off
setlocal EnableDelayedExpansion
set /a counter=0
set "NVC="
for /F %%a in (%~n0.txt) do set "NVC=!NVC! %%a"
:ping
for %%i in (%NVC%) do (
ping %%i -n 1 >nul | find "TTL=" >nul || echo. %%i is offline.
set /a counter+=1
echo %%i is online
set "NVC=!NVC: %%i=!"
)
cls
echo. %counter% machines are online.
if defined NVC goto :ping
echo All machines in %~n0 are online.
pause
The problem is that once the "%%i is offline" line is done, it just continues to the next line and removes it anyway.
Is there a way to skip the 3 lines below the ping if the ping result is bad, and continue with the next iteration in the list?
Note: I'm running this from Server 2008, pinging Win 8.1 machines.
Your first problem is that you're trying to find "TTL=" in output that's been redirected to NUL. Remove that redirection so FIND gets something to search.
Your second problem is a logic error, where even if you execute the || clause, the other lines are executing too. You need to use an ELSE or another IF clause.
Finally, I think you're overcomplicating the processing of your list of IP addresses.
Try this, and see if it makes sense.
#echo off & setlocal
set /a counteron=0
set /a counteroff=0
for /f %%i in (%~n0.txt) do (
ping %%i -n 1 | find "TTL=" >nul
if errorlevel 1 (
set /a counteroff+=1
echo %%i is offline.
) else (
set /a counteron+=1
echo %%i is online
)
)
echo.
echo %counteron% machines are online.
echo %counteroff% machines are offline.

Ping particular host and move the results to file with current time stamp for every hour

I am trying create a batch file which pings a particular host and moves the results to a file with the current time stamp for every hour. I was able to do it continuously, but the I want to know whether there is any script with which I can set the interval for which it runs the ping command.
I am successfully able to print the time stamp, ping response and the able to change the name of the file with current time stamp, but it's happening continuously. I want to do it for a time interval like say for 4hrs continuous ping then move the results to a file.
please help
There is no sane way to do this with a command script only.
What I recommend is to write a script that performs the requested action once.
Use Windows Task Scheduler to call the script every hour.
What I've attempted is by NO means an ideal, much less precise method of doing what you desire (purely in batch), however with some tweaking and refining, or by serving as a potential route/template for similar scripts by more experienced batch scripters, I believe it may be useful:
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1-2 delims=:" %%i in ('echo %time%') do (
set /a hour=%%i+4
set /a minute=%%j
set expected=!hour!:!minute!
echo !expected!
)
for /f "tokens=*" %%i in ('ping 192.168.1.1 -n 1') do (echo %%i>pinglog.txt && goto PING)
:PING
for /f "tokens=1-2 delims=:" %%i in ('echo %time%') do (
set current=%%i:%%j
echo !current!
)
if !current!==!expected! (
goto EOF
) else (
for /f "tokens=* skip=2" %%i in ('ping 192.168.1.1 -n 2 -w 30000') do (
echo %date% %time% %%i>>pinglog.txt && goto PING
)
)
Control the hour or minute interval by adding the relevant value to either, in the lines:
set /a hour=%%i+4 rem Here I've added 4 hours
set /a minute=%%j
Remove the echo !expected! and echo !current! lines if you don't wish to see the temporal progression in the cmd output, which can be minimised while the script is running.

BATCH Alert user to low system memory or disk space

Having tried variations of the following, and with further additional code, what is wrong here? Thanks!
#echo off
goto checkmemorystatus
:checkmemorystatus
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (
set m=%%p
if %m% LSS <threshold> (start echo FREE RAM ALERT: %m% & PING 1.1.1.1 -n 1 -w 60000 >NUL)
goto checkmemorystatus
)
no need for delayed expansion (as there is no need for an additional variable):
#echo off
:checkmemorystatus
PING localhost -n 2 -w 60000 >NUL
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (
if %%p leq 700000 ( echo FREE RAM ALERT: %%p ) else (echo FREE RAM ok : %%p)
goto checkmemorystatus
)
(the code is basically taken from mihai_mandis)
wmic gives you more lines than you want. You already ignored the first line with skip. The above code breaks the for-loop after one run and to ignore the following lines. ( I added a "Free RAM ok" for testing purposes - you may want to delete it)
At the beginning of the script set delayed expansion:
setlocal EnableDelayedExpansion
This will allow you to access variables in for loops in format !var_name!
2.Do not use goto statements inside for block. This will cause for break.
#echo off
setlocal EnableDelayedExpansion
:checkmemorystatus
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (
set mm=%%p
if !mm! LSS <threshold> (
start echo FREE RAM ALERT: !mm!
PING localhost -n 1 -w 60000 >NUL
)
)
goto :checkmemorystatus

Resources