plink automated batch script - windows

How would I create a simple batch script(windows) to close then current plink session if it times out and reconnect automatically?
something like this:
if "plink.exe" == "false" (
"plink command to connect to SSH Server."
)
or maybe
if "plink.exe" == "false" ( "batch to open new plink instance"
)

Here you go.
#echo off
setlocal
:: modify this line as appropriate
set plink_args=-P 22 -i c:\path\to\private.ppk user#host
set errors=0
:loop
:: if "find" exits with a non-zero status, plink.exe isn't running.
( tasklist /fi "IMAGENAME eq plink.exe" | find /i "plink.exe" >NUL && (
set errors=0
) ) || (
start "" plink.exe %plink_args%
set /a "errors+=1"
)
if %errors% geq 5 (
echo Unable to connect %errors% times in a row. Stopping.
goto :EOF
)
:: pause for 10 seconds (-n seconds + 1)
ping -n 11 0.0.0.0 >NUL
goto loop
You know, if you have root access on the ssh server, you could modify sshd_config and have the server send no-op packets every few minutes to prevent connections from timing out due to inactivity. Here's an example snippet of my sshd_config:
# noop anti-idle for 12 hours (10 minutes * 72)
ClientAliveInterval 600
ClientAliveCountMax 72
Add that to your sshd_config and restart the ssh daemon. That might save you from having to do something so hackish on the client-side.

Related

net use in cmd script hangs forever - how to set a timeout if server denies connection

I have a Windows batch file which connects several network drives. It first pings the servers, and if that succeds, it then tries to map the share with net use ...:
SET host=mini3
IF /I NOT %host% == %COMPUTERNAME% (
ping -4 -n 2 -w 1000 %host% | find "TTL=" > NUL
IF !ERRORLEVEL! EQU 0 (
echo Q: == \\%host%\Q_ -- mini3-Volumes
net use Q: \\%host%\Q_ /persistent:yes > NUL && echo OK
) ELSE (
echo %host% not found. Skipping.
)
)
Sometimes, even though the machine is reachable by ping, the net use command hangs forever. The reason it hangs seems due to a misconfiguration in the SMB server, and/or in the Windows Credentials stored on the client.
So when that happens, for whatever reason, I would like to print an error and go on to the next drive to map.
The Windows Timeout command seems to actually be a "delay" command, equivalent of Unix sleep, and not a timeout.
Is there a good way to have a real timeout for a net use command, without aborting the entire .cmd script?
With a few mods I have no problem
key was correcting %errorlevel% as no runtime delay was included/needed
the drive mappings are spawned independently so the tasks can progress
There should be a brief flash if all is well, otherwise if share is not found they should timeout naturally.
Advent is in my case another workstation rather than server. Change that back to mini3
#echo off
SET "host=Advent"
IF /I NOT "%host%"=="%COMPUTERNAME%" (
ping -4 -n 2 -w 1000 %host% | find "TTL=" > NUL
IF %ERRORLEVEL% EQU 0 (
echo Q: == \\%host%\Q_ -- %host%-Volumes
START "Z Drive" net use Z: \\%host%\users /persistent:yes
START "Q Drive" net use Q: \\%host%\Q_ /persistent:yes
REM surplus from above line > NUL && echo OK
) ELSE (
echo %host% not found. Skipping.
)
)
rem delay this file so it waits to let the new connections process above
timeout 2
net use | find ":"

make a batch script foward an IP

Hi so my coworker requested if I could make a script. I am sure what I want it to do and wrote some pseudo code in bash style now of course this not useable for him since he is on Windows. So I tried to implement in a .bat script now here is where my knowledge comes a bit short. What I need the script to do is to connect to a certain VPN-ip if that is not avaible the localsystem should foward it to another VPN so he doesn't need to worry about it. Either one of 2 should always be reachable. But they are never at the same time. This is for test tooling.
Pseudo bashcode
while true
do
From local if
10.10.1.15 avaible connect to it
else
10.168.84.47 connect to it
elseif
try to connect to 10.10.1.15 again && verify that'
else
echo 'error device over VPN unavaible'
My Attempted batch script, I am pretty sure that what I have now is not gonna work
#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 10.10.1.15 >nul: 2>nul:
goto :loop
endlocal
IF EXIST 10.10.1.15 (
is reacheable connect
) ELSE (
netsh interface portproxy add v4tov4 listenport=80 connectaddress=10.10.1.15 fowardaddress=10.168.84.47
)
So far as I know, you can just try to find "ttl=" to determine success/fail for a ping without worrying about all those tokens and different versions of cmd. I'm sure someone will correct me if I'm wrong.
untested
set ip=127.0.0.1
rem 2 pings waiting 900ms for a reply
ping -n 2 -w 900 %ip%|find /i "ttl=">nul || goto :fail
rem If we get here then the ping succeeded
rem do what you want here
goto :eof
:fail
rem If we get here then the ping failed.
rem do what you want here
goto :eof
The || operator basically means "if the previous command fails then do this".

What's the best way to stop a batch script after a specified amount of time?

I'm writing a batch script where I want the user to be able to control how long the script runs. When running it from the command line, the user will pass in a switch like this:
./myscript --stop-after 30
which means that the script will keep doing its job, and check every iteration how much time has passed. If more than a half a minute has passed, then it'll quit. How would I implement this in a batch script?
For reference, here is the code I have so far:
:parseArgs
if "%~1" == "" goto doneParsing
if /i "%~1" == "--stop-after" (
shift
set "duration=%~1"
)
:: Parse some other options...
shift
goto parseArgs
:doneParsing
:: Now do the actual work (psuedocode)
set "start=getCurrentTime"
set "end=%start% + %duration%"
while getCurrentTime < %end% (
:: Do some lengthy task...
)
How would I go about implementing the latter part of the script, after parsing the options?
Thanks for helping.
This is not that trivial. You'll have to do a lot of calculation within your script to cover all cases of full minute, full hour, or even new day. I can think of two different ways. Both are based on two batch files:
1. Termination via taskkill
starter.bat:
#echo off
if "%1"=="" (
set duration=5
) else (
set duration=%1
)
start "myscript" script.bat
ping 127.0.0.1 -n %duration% -w 1000 > nul
echo %duration% seconds are over. Terminating!
taskkill /FI "WINDOWTITLE eq myscript*"
pause
script.bat:
#echo off
:STARTLOOP
echo doing work
ping 127.0.0.1 -n 2 -w 1000 > nul
goto STARTLOOP
For this solution, it's important that you give the window executing your script a unique name inside the line start "myscript" script.bat. In this example, the name is myscript. taskkill /FI "WINDOWTITLE eq myscript*" uses myscript to identify which process to terminate.
However, this might be a bit dangerous. Your script will be killed after x seconds, no matter if an iteration is done or not. So, e.g., write access would be a bad idea.
2. Termination via flag file
starter.bat:
#echo off
if "%1"=="" (
set duration=5
) else (
set duration=%1
)
if exist terminationflag.tmp del terminationflag.tmp
start script.bat
ping 127.0.0.1 -n %duration% -w 1000 > nul
echo %duration% seconds are over. Setting termination flag!
type NUL>terminationflag.tmp
script.bat:
#echo off
:STARTLOOP
echo doing work
ping 127.0.0.1 -n 2 -w 1000 > nul
if not exist terminationflag.tmp goto STARTLOOP
del terminationflag.tmp
echo terminated!
Here, it's important to ensure that your script is allowed to create/delete a file at the current location. This solution is safer. The starter script will wait the given amount of time and then create the flag file. Your script will check after each full iteration whether the flag is there or not. If it's not, it will go on—if it is, it will delete the flag file and terminate safely.
In both solutions ping is used as timeout function. You could also use timeout/t <TimeoutInSeconds> if you are on Windows 2000 or later. However, timeout doesn't always work. It will fail in some scheduled tasks, on build servers, and many other cases. You'd be well advised to stick to ping.

Computer script for auto-reboot on network loss

I am working with a IP Camera network and need a script to run on each individual PC that will perform an auto-reboot when network loss happens. I would like to be able to have the PC ping the servers IP every 5 minutes and upon loss of connectivity the PC will reboot. Each PC has a Camera viewer but periodically looses network connection with the NVR. I found almost the same issue/solution here: http://www.cam-it.org/index.php?topic=2786.0
However the script provided didn't work for me. Below is the script I found and tried but didn't function the way I needed.
#Echo off
REM Put REM in front of Echo off to view the file output
REM ---------------------------------------------------------
REM WATCHDOG.CMD
REM Restarts PC after 3 unsuccessful attempts to PING the
REM POE switch
REM --------------------------------------------------------
SET COUNT=C:\Temp\WATCHDOG.txt
SET POESWITCH=192.168.1.253
SET ERRFLG=0
IF EXIST "%COUNT%" (
SET /P ERRFLG= <%COUNT%
)
IF %ERRFLG% GTR 2 (
Echo Restarting PC in 60 seconds. Run SHUTDOWN -a to abort.
DEL %COUNT%
SHUTDOWN -r -t 60 -f
GOTO :EOF
)
PING -n 1 %POESWITCH%|findstr /I /C:"timed out" /C:"unreachable" /C:"general failure"
if %ERRORLEVEL% == 1 Goto Done
SET /a ERRFLG +=1
ECHO %ERRFLG% > %COUNT%
:Done
(http://www.cam-it.org/index.php?topic=2786.0)
Any suggestions would be greatly appreciated.
Thanks,
Jordan
Add the reboot command and it should work for you to test a URL/IP address every 300 seconds
#echo off
set ip=www.google.com
:loop
ping -n 2 %ip% |find "TTL=" >nul || echo reboot command here
ping -n 300 localhost >nul
goto :loop

Test for internet intermittency

I was wondering if there is a way to write a cmd script or something for Windows that will allow me to tell when my internet connection has severed.
In Ubuntu, I would have written a shell script to ping Google once per second and if it is impossible record the time etc etc.
Is it possible to do a similar thing in Windows?
There may be a better way to monitor the connection status. But here is a Windows batch implementation of the logic you specified.
#echo off
setlocal enableDelayedExpansion
set log="internetStatus.txt"
set "status="
>>%log% echo %date% %time%: Begin monitoring
for /l %%A in () do (
>nul ping -n 2 -w 1000 google.com && (
if "%status%"=="FAIL" (
>>%log% echo %date% %time%: internet connection succeeded
set "status=OK"
)
) || (
if "%status%"=="OK" (
>>%log% echo %date% %time%: Internet connection to google.com failed
set "status=FAIL"
)
)
)

Resources