@ECHO OFF && PUSHD "%~dp0" && SETLOCAL CALL :PINGCHECK "%~1" nircmd.exe speak text "PING RECEIVED. HOST BACK ONLINE" 7 60 ENDLOCAL && POPD && GOTO :EOF :PINGCHECK ECHO CHECKING %~1 ping.exe -n 1 %~1 -w 5000 | FIND /C "Reply from %~1" | FIND "1" >nul 2>&1 IF ERRORLEVEL 1 CALL :PINGCHECK "%~1" ELSE EXIT /B @ECHO OFF && PUSHD "%~dp0" && SETLOCAL && SETLOCAL ENABLEDELAYEDEXPANSION && SETLOCAL ENABLEEXTENSIONS SET _CRYPTDRIVE=%~d0 SET PATH=%_CRYPTDRIVE%PP;%_CRYPTDRIVE%PPbin;%PATH% SET _PUTTYBIN=%_CRYPTDRIVE%PPPputty.exe SET _PSERVER=solar.power.com SET _PPORT=22 SET _PSESSION=newclean-tunnel SET _ADMINUSER=admin SET _RUNUSER=life REM SAY CHECKING PLINK OUT LOUD CALL :SPEAK "Checking Putty" ECHO "CHECKING PUTTY" REM IF NOT EXIST "%_CRYPTDRIVE%" ( CALL :SPEAK "Crypt Not Mounted" AT|FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >nul 2>&1 pskill.exe -t putty >nul 2>&1 pskill.exe -t thunderbird >nul 2>&1 pskill.exe -t ThunderbirdPortable >nul 2>&1 pskill.exe -t Firefox >nul 2>&1 pskill.exe -t FirefoxPortable >nul 2>&1 pskill.exe -t GC >nul 2>&1 EXIT ) REM CREATE AT JOB TO RUN THIS SCRIPT EVERY 5 MINUTES CALL :CREATEATJOB pslist putty >nul 2>&1 IF ERRORLEVEL 1 psexec.exe -i 0 -e -d -u %_RUNUSER% %_PUTTYBIN% -load %_PSESSION% REM KILL MULTIPLE PSEXEC's CALL :KILLDUPES "psexec.exe" REM KILL MULTIPLE CMD.EXE's CALL :KILLDUPES "cmd.exe" REM REACHABLE SERVER CHECK CALL :PINGCHECK %_PSERVER% REM CHECK FOR INACTIVE PUTTY CALL :PUTTYCHECK REM CHECK PORT IS LISTENING (FOR SOCKISFIED TUNNEL) CALL :PORTCHECK %_PPORT% REM CALL :SPEAK "OK" SLEEP 100 && ECHO "OK" && SLEEP 1 && ENDLOCAL && POPD && EXIT REM ======================================================================================= REM = SPEAK - Speak text REM ======================================================================================= :SPEAK nircmd.exe speak text "%~1" 5 60 ECHO "%~1" EXIT /B REM ======================================================================================= REM = RESTARTPLINK - Sleeps for %1 number of seconds REM ======================================================================================= :RESTARTPLINK CALL :SPEAK "%~1 ReSTARTing Plink" REM runas /savecred /user:admin "%_PUTTYBIN% -load %_PSESSION%" psexec.exe -i 0 -e -d -u %_RUNUSER% %_PUTTYBIN% -load %_PSESSION% EXIT EXIT /B REM ======================================================================================= REM = PORTCHECK - Check that Port is being used (for tunnels) REM ======================================================================================= :PORTCHECK netstat.exe -n -v -a -p TCP | FIND "ESTABLISHED" | FIND ":%~1" >nul 2>&1 IF ERRORLEVEL 1 CALL :RESTARTPLINK "PORT CHECK FAILED" EXIT /B REM ======================================================================================= REM = INACTIVEPUTTYCHECK - Check for inactive putty windows REM ======================================================================================= :PUTTYCHECK tasklist.exe /V /NH /FI "WINDOWTITLE eq PuTTY (inactive)" 2>nul|FIND "INFO: " >nul 2>&1 IF ERRORLEVEL 1 taskkill.exe /T /F /FI "WINDOWTITLE eq PuTTY (inactive)" >nul 2>&1 :: MAKE SURE ONLY 1 putty is running that is connected to the remote server netstat.exe -n -a -o -p TCP | FIND ":%_PPORT%" | FIND /C ":%_PPORT%" | FIND "1" >nul 2>&1 IF ERRORLEVEL 1 ( tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq putty.exe" 2>nul | FIND /C "Running" | FIND "1" >nul 2>&1 IF ERRORLEVEL 1 ( REM kill all running puttys (owned by system) FOR /F "usebackq tokens=2 skip=2" %%p IN (`tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq putty.exe"`) DO taskkill.exe /F /PID %%p /T >nul 2>&1 CALL :RESTARTPLINK "EXTRA PUTTY FOUND" ) ) EXIT /B REM ======================================================================================= REM = PINGCHECK - PING address to make sure it is reachable REM ======================================================================================= :PINGCHECK PING %~1 -n 1 -w 5000 | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 ( PING google.com -n 1 -w 500 | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 ( CALL :SPEAK "CHECK INTERNET CONNECTION" && SLEEP 60 ) PING google.com -n 1 -w 5000 | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 ( CALL :SPEAK "CHECK INTERNET CONNECTION" && SLEEP 60 ) PING google.com -n 1 -w 5000 | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 ( CALL :SPEAK "KILL SOCKS PROGRAMS" SLEEP 100 pskill.exe -t putty >nul 2>&1 pskill.exe -t thunderbird >nul 2>&1 pskill.exe -t ThunderbirdPortable >nul 2>&1 ) ) EXIT /B REM ======================================================================================= REM = KILLDUPES - kills duplicate processes, except for the one with lowest pid REM ======================================================================================= :KILLDUPES REM Check that more than 1 process is running tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1 IF NOT ERRORLEVEL 1 EXIT /B REM Create Filename in current dir (of this script) SET _T=%TIME: =0%&&SET _T=!_T::=-!&&SET _T=%~dp0%!_T:~0,-2!log REM Create the file in the same dir as this script named for date and sorted by PID tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | SORT /+29 > "%_T%" REM Check that the file was created or exit IF NOT EXIST "%_T%" ( CALL :SPEAK "FILE CREATION FAILED" && EXIT /B ) REM kill all the processes found except for 1, do not kill the process with the lowest pid number FOR /F "tokens=2 skip=2" %%p IN (%_T%) DO taskkill.exe /F /PID %%p /T REM erase the file REM ERASE /Q "%_T%" >nul 2>&1 REM check that the file was erased REM IF EXIST "%_T%" ( CALL :SPEAK "ERASE FILE FAILED" && EXIT /B ) EXIT /B REM ======================================================================================= REM = CREATEATJOB - runs job (START this file) every 5 minutes REM ======================================================================================= :CREATEATJOB :: delete all putty AT jobs AT | FIND /C "%~f0" | FIND "1" >nul 2>&1 IF ERRORLEVEL 1 ( AT|FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >nul 2>&1 ) SET /A H=!TIME:~0,2!&& SET M=!TIME:~3,2! SET Y=%H%:%M%&& SET /A M+=5 IF !M! GEQ 61 ( SET /A H+=1&&SET /A M-=61 ) IF !H! GEQ 24 SET /A H-=24 SET M=0!M!&& SET H=0!H! :: create AT job AT %H:~-2%:%M:~-2% /INTERACTIVE %ComSpec% /E:ON /D /Q /C START /B /MIN %ComSpec% /E:ON /D /Q /C "%~f0" >nul EXIT /BAdvanced Batch File ^ This is the main batch file example which you can download here. Other than some minor changes this is the actual script I use at work when I logon to my PC. The first thing it does is mount an encrypted TrueCrypt Drive where all of my files and settings are located. It also starts a putty session named "1" that I configured to start a few encrypted tunnels and socks proxies so that my email Thunderbird and Website IDE Dreamweaver and other network apps can communicate 100% encrypted and my real location becomes hidden (thanks socks!). I might come back later and add comments if I get any kind of response for this article, and because it's such a unique and low-traffic topic, I will try to answer any questions added with the comment form. Starting the Script ^ The first line is of my own design and is perhaps the coolest hack in the script. I use this 1 line to start pretty much all of my .bat files. @ECHO OFF&& SETLOCAL&& PUSHD "%~dp0"&& SETLOCAL ENABLEDELAYEDEXPANSION&& SETLOCAL ENABLEEXTENSIONS&& SET V=5&& IF NOT "!V!"=="5" (ECHO DelayedExpansion Failed&& GOTO :EOF)SCRIPT VARIABLES ^ These are all local to this script thanks to the SETLOCAL above, so they won't exist outside the scripts execution environment. REM ** Various vars for output used by functions SET P1=^^^>^^^>^^^> SET P2=++ SET P3=:: SET L1=+==============================================================================================================+ SET L2=+--------------------------------------------------------------------------------------------------------------+ REM ** administrator username, unless changed for more security, its Administrator SET ADMINUSER=admin REM ** runuser is the username you use when running this script SET RUNUSER=bill REM ** Custom COMSPEC for running cmd.exe SET _SCOM=%COMSPEC% /E:ON /F:ON /D /Q /T:0C /C REM ** Custom START command SET _START=START /WAIT /MIN /B %_SCOM%MAIN PROGRAM EXECUTION ^ This is where the main code starts, note how small it is thanks to the use of functions (labels/call/goto). Read the comments in this area (start with :: or REM ) to see the extent of this script. The gold is in the functions. :: Only allow certain users to run this script or die (prevents global STARTup or service running it) CALL :CHECKUSERVALID %RUNUSER% %ADMINUSER% :: Mount the truecrypt container CALL :CRYPTMOUNT "L" "%SYSTEMDRIVE%CRYPTLEONARDO" "%SYSTEMDRIVE%CRYPTLEONARDO_KEY" :: Start Mozilla Firefox CALL :RUNONE "C:Program FilesMozilla Firefoxfirefox.exe" :: Start Thunderbird Portable CALL :RUNONE "L:PPPputty.exe" "/MIN" -load 1 :: Start Thunderbird Portable CALL :RUNONE "L:PTBThunderbirdPortable.exe" "/MIN" :: Start Adobe Dreamweaver CS4 CALL :RUNONE "C:Program FilesAdobeAdobe Dreamweaver CS4Dreamweaver.exe" "/MIN" :: Start LightScreen Portable CALL :RUNONE "L:PLPLightscreenPortable.exe" /B /B :: Start Google Chrome Portable ( GREAT to use for pandora/last.fm as its so low mem ) CALL :RUNONE "L:PGCGC.exe" "/NORMAL" :: Start Adobe Photoshop CS4 CALL :RUNONE "%ProgramFiles%AdobeAdobe Photoshop CS4Photoshop.exe" "/MAX"Exit Script ^ This is the last line executed in the Main, it forces the script to exit cleanly at this point, otherwise the functions below would all get executed. This is what allows the use of all the functions below. I end all my scripts MAIN with this. REM ** EXIT Script CALL :MDYE "EOF" && POPD && ENDLOCAL && GOTO :EOFSCRIPT FUNCTIONS ^ Now then, onto the MEAT of the script, all the functions. These functions are designed for global use in other batch files, so that the only modification when you make a new batch is the above variables and main execution.. If you know much about batch files you will realize that creating these functions was a very painful process in some cases.. I freakin hate windows! Anyway, enjoy! CRYPTMOUNT - mounts a truecrypt container and returns to CALLer. On fail, quit ^ REM REM CALL :CRYPTMOUNT "%LEONARDO%" "%LEONARDO_FILE%" "%LEONARDO_KEY%" REM CALL :CRYPTMOUNT "L" "%SYSTEMDRIVE%CRYPTLEONARDO" "%SYSTEMDRIVE%CRYPTLEONARDO_KEY" REM REM :: print the settings REM :: CALL :MP 3 "DRIVE: %DRIVE%"&&CALL :MP 3 " FILE: %FILE%"&&CALL :MP 3 " KEY: %KEY%"&&CALL :MP 3 " VOL: %VOL%":CRYPTMOUNT SET DRIVE=%~1&& SET FILE=%~2&& SET KEY=%~3&& SET VOL=!FILE:~0,3! CALL :MP 1 "Mounting TrueCrypt on %DRIVE% from %FILE%" :: Check for Truecrypt or die CALL :EXISTORQUIT "%ProgramFiles%TrueCryptTrueCrypt.exe" && CALL :EXISTORQUIT "%FILE%" && CALL :EXISTORQUIT "%KEY%" :: checks that MOUNTVOL works and the drive containing the truecrypt container file is present or dies MOUNTVOL %VOL% /L 2>NUL | FIND "\?Volume{" >NUL 2>&1 IF ERRORLEVEL 1 CALL :MDYE "%VOL% NOT FOUND" REM ** Converts G: to its \?Volume{234234} equivalent for greater portability FOR /F %%i IN ('MOUNTVOL %VOL% /L') DO @SET VOL=%%i%FILE:~3% :: IF the drive is already mounted then continue, otherwise try to mount MOUNTVOL %DRIVE%: /L >NUL 2>&1 IF NOT ERRORLEVEL 1 ( CALL :MP 2 "%DRIVE% ALREADY MOUNTED" && EXIT /B ) ELSE ( START "Mounting TrueCrypt" /D"%ProgramFiles%TrueCrypt" /MIN /B TrueCrypt.exe /c n /b /q background /h n /k %KEY% /l %DRIVE% /p /v %VOL% && SLEEP 10 ) :: try again in case of bad password and accidental keypress MOUNTVOL %DRIVE%: /L >NUL 2>&1 IF ERRORLEVEL 1 (START "Mounting TrueCrypt" /D"%ProgramFiles%TrueCrypt" /MIN /B TrueCrypt.exe /c n /b /q background /h n /k %KEY% /l %DRIVE% /p /v %VOL% && SLEEP 10) :: IF it still doesnt exist then quit MOUNTVOL %DRIVE%: /L >NUL 2>&1 IF ERRORLEVEL 1 CALL :MDYE "Failed to mount %FILE% on %DRIVE%" CALL :MF && ENDLOCAL && EXIT /B EXIT /BRUNONE - Starts one instance of executable after verifying it exists and is not already running. ^ REM %~1 is location of executatable REM %~2 is optional (unless %~3 is used) START parameters REM %~3 is optional parameters for executable REM REM CALL :RUNONE "L:PLPLightscreenPortable.exe" "/MAX" "/HIDE":RUNONE SETLOCAL CALL :MP 1 "Starting %~n1" :: SLEEP FOR NICENESS, LOCAL VARS _P2 and _P3 SLEEP 2 && SETLOCAL SET P=%~1 ECHO %P%|FIND " " >NUL 2>&1 IF NOT ERRORLEVEL 1 ( PUSHD "%~dp1" && SET P=%~nx1 ) :: SET _P2 TO DEFAULT TO "/MIN" IF EMPTY SET _P2=/MIN IF NOT " %~2" == " " SET _P2=%~2 IF NOT " %~3" == " " SET _P3=%~3 IF NOT " %~4" == " " SET _P4=%~4 :: CHECK THAT EXECUTABLE EXISTS CALL :EXISTORQUIT "%~1" REM ECHO START %_P2% /D"%~dp1" %P% %_P3% %_P4%&& PAUSE&& :: CHECK FOR EXISTING PROCESSNAME ( %~n1 is file name without ext, %~nx1 is the file name and extension. ) pslist.exe /e %~n1 >NUL 2>&1 IF ERRORLEVEL 1 (START %_P2% /D"%~dp1" %P% %_P3% %_P4% ) ELSE (CALL :MP 2 "%~n1 already running!" ) ENDLOCAL && EXIT /BADMINRUNONE - Runs %1 with admin rights IF neccessary ^ :ADMINRUNONE CALL :MP 3 "Exec %~1 as %ADMINUSER%" :: Check that file exists CALL :EXISTORQUIT "%~1" :: test for rights to the task scheduler :: %SYSTEMDRIVE%WINDOWSsystem32cmd.exe /E:ON /D /Q /T:0C /C START /WAIT /MIN /B %SYSTEMDRIVE%WINDOWSsystem32cmd.exe /E:ON /D /Q /T:0C /C %~1 AT >NUL 2>&1 IF ERRORLEVEL 1 ( RUNAS /noprofile /user:%USERDOMAIN%%ADMINUSER% "%~1" ) ELSE ( %COMSPEC% /E:ON /D /Q /T:0C /C "%~1" ) SLEEP 2 && CALL :MF && EXIT /BCHECKUSERVALID - checks that defined username equals %ADMINUSER% or %RUNUSER%, then returns to CALLer ^ :CHECKUSERVALID :: EXIT IF USERNAME IS NOT DEFINED, CATCHES SYSTEM ACCOUNTS TRYING TO RUN WHEN IN GLOBAL STARTUP IF NOT DEFINED USERNAME EXIT SETLOCAL SET UP=no SET _P1= %~1 SET _P2= %~2 IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes) IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes) IF NOT "%_P1%" == " " ( IF /I "%~1" == "%USERNAME%" SET UP=yes) IF /I "bill" == "%USERNAME%" SET UP=yes IF /I "newbill" == "%USERNAME%" SET UP=yes IF /I "max" == "%USERNAME%" SET UP=yes IF /I NOT "%UP%" == "yes" EXIT ENDLOCAL EXIT /BSETPROMPT - sets prompt, then returns to CALLer ^ REM = [user@MACHINE] [C:DRPEPPERSCRIPTS] REM = > REG /?:SETPROMPT set PROMPT=$_[%USERNAME%@%USERDOMAIN%]$S[$P]$_$M$G && EXIT /BBEEP - beeps once, then returns to CALLer ^ The character after the echo is the actual BEL char, so unless you have my source file, you will need to copy a literal BEL char here to make it beep. :BEEP @ECHO # && EXIT /BMSETCOLOR - SET colors for screen, then returns to CALLer ^ REM REM 0 = Black 8 = Gray REM 1 = Blue 9 = Light Blue REM 2 = Green A = Light Green REM 3 = Aqua B = Light Aqua REM 4 = Red C = Light Red REM 5 = Purple D = Light Purple REM 6 = Yellow E = Light Yellow REM 7 = White F = Bright White REM:MSETCOLOR COLOR %~1 && EXIT /BMSETCONSOLE - sets the cols and lines of current screen buffer, then returns to CALLer ^ :MSETCONSOLE MODE CON COLS=%~1 LINES=%~2 && EXIT /BPARAMTEST - tests params, then returns to CALLer ^ :PARAMTEST ECHO. && CALL :MP 1 "PARAMTEST CALLED WITH: %*" && ECHO %L1% SET _P= %~1 IF NOT "%_P%" == " " ( ECHO %%1 = %1 && ECHO %%~f1 = %~f1 && ECHO %%~d1 = %~d1 && ECHO %%~p1 = %~p1 ECHO %%~n1 = %~n1 && ECHO %%~x1 = %~x1 && ECHO %%~s1 = %~s1 && ECHO %%~dp1 = %~dp1 ECHO %%~nx1 = %~nx1 && ECHO %%~$PATH:1 = %~$PATH:1 && ECHO %%~dp$PATH:1 = %~dp$PATH:1 && ECHO %L1% ) SET _P= %~2 IF NOT "%_P%" == " " ( ECHO %%2 = %2 && ECHO %%~f2 = %~f2 && ECHO %%~d2 = %~d2 && ECHO %%~p2 = %~p2 ECHO %%~n2 = %~n2 && ECHO %%~x2 = %~x2 && ECHO %%~s2 = %~s2 && ECHO %%~dp2 = %~dp2 ECHO %%~nx2 = %~nx2 && ECHO %%~$PATH:2 = %~$PATH:2 && ECHO %%~dp$PATH:2 = %~dp$PATH:2 && ECHO %L1% ) SET _P= %~3 IF NOT "%_P%" == " " ( ECHO %%3 = %3 && ECHO %%~f3 = %~f3 && ECHO %%~d3 = %~d3 && ECHO %%~p3 = %~p3 ECHO %%~n3 = %~n3 && ECHO %%~x3 = %~x3 && ECHO %%~s3 = %~s3 && ECHO %%~dp3 = %~dp3 ECHO %%~nx3 = %~nx3 && ECHO %%~$PATH:3 = %~$PATH:3 && ECHO %%~dp$PATH:3 = %~dp$PATH:3 && ECHO %L1% ) SET _P= %~4 IF NOT "%_P%" == " " ( ECHO %%4 = %4 && ECHO %%~f4 = %~f4 && ECHO %%~d4 = %~d4 && ECHO %%~p4 = %~p4 ECHO %%~n4 = %~n4 && ECHO %%~x4 = %~x4 && ECHO %%~s4 = %~s4 && ECHO %%~dp4 = %~dp4 ECHO %%~nx4 = %~nx4 && ECHO %%~$PATH:4 = %~$PATH:4 && ECHO %%~dp$PATH:4 = %~dp$PATH:4 && ECHO %L1% ) SET _P= %~5 IF NOT "%_P%" == " " ( ECHO %%5 = %5 && ECHO %%~f5 = %~f5 && ECHO %%~d5 = %~d5 && ECHO %%~p5 = %~p5 ECHO %%~n5 = %~n5 && ECHO %%~x5 = %~x5 && ECHO %%~s5 = %~s5 && ECHO %%~dp5 = %~dp5 ECHO %%~nx5 = %~nx5 && ECHO %%~$PATH:5 = %~$PATH:5 && ECHO %%~dp$PATH:5 = %~dp$PATH:5 && ECHO %L1% ) SET _P= %~6 IF NOT "%_P%" == " " ( ECHO %%6 = %6 && ECHO %%~f6 = %~f6 && ECHO %%~d6 = %~d6 && ECHO %%~p6 = %~p6 ECHO %%~n6 = %~n6 && ECHO %%~x6 = %~x6 && ECHO %%~s6 = %~s6 && ECHO %%~dp6 = %~dp6 ECHO %%~nx6 = %~nx6 && ECHO %%~$PATH:6 = %~$PATH:6 && ECHO %%~dp$PATH:6 = %~dp$PATH:6 && ECHO %L1% ) SET _P= %~7 IF NOT "%_P%" == " " ( ECHO %%7 = %7 && ECHO %%~f7 = %~f7 && ECHO %%~d7 = %~d7 && ECHO %%~p7 = %~p7 ECHO %%~n7 = %~n7 && ECHO %%~x7 = %~x7 && ECHO %%~s7 = %~s7 && ECHO %%~dp7 = %~dp7 ECHO %%~nx7 = %~nx7 && ECHO %%~$PATH:7 = %~$PATH:7 && ECHO %%~dp$PATH:7 = %~dp$PATH:7 && ECHO %L1% ) SLEEP 3 CALL :MF EXIT /BPARAMTESTHELP - show params help, then returns to CALLer ^ :PARAMTESTHELP ECHO %%~1 Expands %%1 and removes any surrounding quotation marks ECHO %%~f1 Expands %%1 to a fully qualified path name. ECHO %%~d1 Expands %%1 to a drive letter. ECHO %%~p1 Expands %%1 to a path. ECHO %%~n1 Expands %%1 to a file name. ECHO %%~x1 Expands %%1 to a file extension. ECHO %%~s1 Expanded path contains short names only. ECHO %%~a1 Expands %%1 to file attributes. ECHO %%~t1 Expands %%1 to date and time of file. ECHO %%~z1 Expands %%1 to size of file. ECHO %%~dp1 Expands %%1 to a drive letter and path. ECHO %%~nx1 Expands %%1 to a file name and extension. ECHO %%~ftza1 Expands %%1 to a dir-like output line. ECHO %%~$PATH:1 Searches the dirs in PATH expanding %%1 to fully qualified name of first found. If var name isn't defined or the files not found, expands to empty string. ECHO %%~dp$PATH:1 Searches the directories listed in the PATH environment variable for %%1 and expands to the drive letter and path of the first one found. CALL :MF EXIT /BEXAMINEFILE - FINDs useful strings in file, then returns to CALLer ^ :EXAMINEFILE CALL :MP 1 "Examine File %~1" CALL :EXISTORQUIT "%~1" STRINGS "%~1" | FINDSTR /R /C:"[A-Z][A-Z]=" CALL :MF EXIT /BADMINSHELL - sets prompt, then returns to CALLer ^ :ADMINSHELL CALL :MP 1 "Creating Admin Shell" CALL :EXISTORQUIT "%SYSTEMROOT%system32runas.exe" START %SYSTEMROOT%system32runas.exe /profile /savecred /user:%ADMINUSER% "%COMSPEC% /T:0C /E:ON /F:ON /K cmd.exe /K cd C:CRYPTBIN" CALL :MF EXIT /BEXISTORQUIT - checks %~1 exists, IF it does returns to CALLer, otherwise, quit ^ :EXISTORQUIT :: CALL :MP 1 "Checking for %~1" IF NOT EXIST "%~1" CALL :MDYE "%~1 NOT FOUND" EXIT /BRR - IF file %1 EXISTs then :MT "Removing %1" then :MF, then ( or IF %1 not EXISTs) returns to CALLer ^ :RR CALL :MP 1 "Removing %~1" IF EXIST "%~1" ERASE /q "%~1" CALL :MF && EXIT /BLOCKDOWN - locks workstation, then returns to CALLer (pointless) ^ :LOCKDOWN RUNDLL32 USER32.DLL,LockWorkStation && EXIT /BSHUTDOWNIN - initiates shutdown, then returns to CALLer (pointless) ^ REM shutdown /a aborts:SHUTDOWNIN SHUTDOWN -r -t "%~1" && EXIT /BLISTSERVICES - lists services, then returns to CALLer ^ :LISTSERVICES SC query state= all type= all | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i SC query | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i EXIT /BTASKS - Advanced Tasklisting ^ :TASKS SET _P=%~1 SET _PP= %~1 IF "%_PP%" == " " EXIT /B REM SORTABLES IF /I "%_P%" == "pid" ( tasklist.exe /V /NH | SORT /+29 && EXIT /B ) IF /I "%_P%" == "size" ( tasklist.exe /V /NH | SORT /+59 && EXIT /B ) IF /I "%_P%" == "user" ( tasklist.exe /V /NH | SORT /+89 && EXIT /B ) IF /I "%_P%" == "time" ( tasklist.exe /V /NH | SORT /+138 && EXIT /B ) IF /I "%_P%" == "window" ( tasklist.exe /V /NH | SORT /+152 && EXIT /B ) REM FILTERS IF /I "%_P%" == "image" ( tasklist.exe /V /NH /FI "IMAGENAME eq %~2" && EXIT /B ) IF /I "%_P%" == "username" ( tasklist.exe /V /NH /FI "USERNAME eq %~2" && EXIT /B ) IF /I "%_P%" == "running" ( tasklist.exe /V /NH /FI "STATUS eq Running" && EXIT /B ) IF /I "%_P%" == "status" ( tasklist.exe /V /NH /FI "STATUS eq %~2" && EXIT /B ) CALL :MF EXIT /BSPEAK - Speak text ^ :SPEAK REM ECHO "%~1" nircmd.exe speak text "%~1" 5 60 && EXIT /BMF - SLEEPs for 1 second, then prints out completed message, followed by 2 blank lines, then returns to CALLer ^ :MF SLEEP 1 && ECHO [COMPLETED] && ECHO. && ECHO. && EXIT /BMM - prints blank line, L1, changes title of the interpreter window to %~1, prints >>> %~1..., L2, blank line, then returns to CALLer ^ :MM SLEEP 1 && ECHO. && ECHO %L1% && title +++ %~1... && ECHO %P1% %~1... && ECHO %L2% && ECHO. && EXIT /BMT - prints blank line, L1, changes title of the interpreter window to %~1, prints >>> %~1..., L2, blank line, then returns to CALLer ^ :MT CALL :MM "%~1" && CALL :SPEAK "%~1" && EXIT /BMP - Print Output, then returns to CALLer ^ :MP IF "%~1" == "1" ECHO %P1% %~2 && EXIT /B IF "%~1" == "2" ECHO %P2% %~2 && ECHO. && EXIT /B IF "%~1" == "3" ECHO %P3% %~2 && EXIT /B EXIT /BMP3 - ECHO %~1, speak %~1 with nircmd.exe, then returns to CALLer ^ :MP3 CALL :MP 1 "%~1" && CALL :SPEAK "%~1" && EXIT /BMDYE - exit script with message %~1, then returns to CALLer ^ :MDYE SETLOCAL SET _M= %~1 IF NOT "%_M%" == " " SET _M=REASON: %~1 CALL :MP 1 "EXITING SCRIPT... %_M%" && ECHO. && ECHO. ENDLOCAL && EXIT /BMKILL - exit cmd processor with message %~1 ^ :MKILL SETLOCAL SET _M= %~1 IF NOT "%_M%" == " " SET _M=REASON: %~1 ECHO. && ECHO. && CALL :MP 1 "EXITING CMD WINDOW IN 3 SECONDS... %_M%" && ECHO. && ECHO. && SLEEP 3 ENDLOCAL && EXIT && EXIT && EXITEOF: Thoughts ^ So what did you think? I have around 20 batch scripts that utilize these and other functions to do all sorts of cool things. One takes a screenshot of my desktop every 10 minutes and saves it for a real-cool archive of my activity. Another lets me edit a boot.ini file with 1 command.. And another runs when I insert a USB drive to automatically mount a truecrypt volume and create SSH tunnels in the background by using Plink, AT, and the runas.exe command. If you want to program, please use linux... If you need to write a Windows batch file, I hope this helps. -------------------------------------------------------------------------------- September 3rd, 2010 ¦Feed for this Entry ¦Trackback ¦mod_rewrite htaccess Please Comment! Cancel reply Your email address is not saved. Reader Comments AskApache ~December 4, 2012 @ 4:54 am@John Normally I'd say GRTFM, but since this is windows batch, hey what the heck. Here ya go. @ECHO OFF SET NPEXE=C:\Program Files (x86)\Notepad++\notepad++.exe SET NPIMG=notepad++.exe SET NPINSTALLER=C:\Program Files (x86)\Notepad++\notenpp.6.2.Installer.exe /S tasklist.exe /V /FO TABLE /NH /FI "IMAGENAME eq %NPIMG%" 2>NUL | FIND "%NPIMG% " >NUL 2>&1 IF ERRORLEVEL 1 ( ECHO %NPIMG% not running, starting START /D"C:\Program Files (x86)\Notepad++" %NPIMG% ) ELSE ( ECHO %NPIMG% already running, killing tskill %NPIMG% ECHO Starting installer START /D"C:\Program Files (x86)\Notepad++" %NPINSTALLER% SLEEP 5 ECHO Starting notepad++ START /D"C:\Program Files (x86)\Notepad++" %NPIMG% )jack ~November 2, 2012 @ 1:13 pmplease help me make this shorter and easier @echo off color 09 echo loading 1 % ping localhost -n 1 >nul cls echo loading 2 % ping localhost -n 1 >nul cls echo loading 3 % ping localhost -n 1 >nul ... echo loading 100 % ping localhost -n 2 >nulJohn ~October 25, 2012 @ 9:32 amHi - Can someone help me. Im trying to create a batch file please that would do the following: 1.check to see if application is running 2.if its open then close running app 3.then run installation.exe 4.then relaunch application I have some of it already mentioned below. But im missing some of the other commands on the script So in other words something like this. please fill what im missing. @echo off Var opened = false If (notepad++ is opened) tskill notepad++ > NUL opened = true c:notenpp.6.2.Installer.exe /S if (opened = true) start "" "C:Program Files (x86)Notepad++notepad++.exe"Please HELP!!!! AskApache ~February 28, 2012 @ 9:56 am@ECHO OFF&& SETLOCAL&& PUSHD "%~dp0"&& SETLOCAL ENABLEDELAYEDEXPANSION&& SETLOCAL ENABLEEXTENSIONS&& SET V=5&& IF NOT "!V!"=="5" (ECHO DelayedExpansion Failed&& GOTO :EOF) REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ REM ++ ++ REM ++ SCRIPT LOCAL VARIABLES ++ REM ++ ++ REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SET _FIREFOXBIN=C:Program FilesMozilla Firefoxfirefox.exe SET PATH=%ProgramFiles%;%PATH% SET _PLOG=L:PPPatlog.log REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ REM ++ ++ REM ++ MAIN PROGRAM EXECUTION ++ REM ++ ++ REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ REM CREATE AT JOB TO RUN THIS SCRIPT EVERY 5 MINUTES CALL :CREATEATJOB CALL :STARTFIREFOX :: CHECK ONLY 1 FIREFOX IS RUNNING CALL :FIREFOXCHECKMULTI POPD && ENDLOCAL && EXIT && EXIT GOTO :EOF REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ REM ++ ++ REM ++ SCRIPT FUNCTIONS ++ REM ++ ++ REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ REM ========================================================================================================================================================================= REM = STARTFIREFOX REM ========================================================================================================================================================================= :STARTFIREFOX ECHO.&& ECHO STARTING FIREFOX CALL :KILLDUPES "firefox.exe" START "firefox" /HIGH /MIN "%_FIREFOXBIN%" IF ERRORLEVEL 1 ( CALL :SPEAK "FAILED. START FIREFOX" ) ELSE ( ECHO OK ) EXIT /B REM ======================================================================================= REM = CREATEATJOB - runs job (START this file) every 5 minutes REM ======================================================================================= :CREATEATJOB ECHO.&& ECHO CREATE AT JOB AT | FOR /F "tokens=1" %%i IN ('FIND /I "%~f0"') DO AT %%i /delete /yes >NUL 2>&1 SET /A H=!TIME:~0,2!&& SET M=!TIME:~3,2! SET Y=%H%:%M%&& SET /A M+=5 IF !M! GEQ 60 ( SET /A H+=1&&SET /A M-=60 ) IF !H! GEQ 24 SET /A H-=24 SET M=0!M!&& SET H=0!H! AT %H:~-2%:%M:~-2% /INTERACTIVE %ComSpec% /E:ON /D /Q /C START /MIN %ComSpec% /E:ON /D /Q /C "%~f0" >NUL 2>&1 ECHO OK EXIT /B REM ======================================================================================= REM = KILLDUPES - kills duplicate processes, except for the one with lowest pid REM ======================================================================================= :KILLDUPES ECHO.&& ECHO KILLING DUPLICATE FIREFOXS REM Check that more than 1 process is running ::tasklist.exe /V /NH /FI "IMAGENAME eq %~1" /FI "USERNAME eq SYSTEM" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1 tasklist.exe /V /NH /FI "IMAGENAME eq %~1" 2>nul | FIND /C "K Running" | FIND "1" >nul 2>&1 IF NOT ERRORLEVEL 1 EXIT /B REM Create Filename in current dir (of this script) SET _CMDS=%TEMP%killdupes.log REM Create the file in the same dir as this script named for date and sorted by PID tasklist.exe /V /NH /FI "IMAGENAME eq %~1" 2>nul | SORT /+29 > "%_CMDS%" REM Check that the file was created or exit IF NOT EXIST "%_CMDS%" ( CALL :SPEAK "FILE CREATION FAILED" && EXIT /B ) REM kill all the processes found except for 1, do not kill the process with the lowest pid number FOR /F "usebackq tokens=2 skip=2" %%p IN (`type "%_CMDS%"`) DO taskkill.exe /F /PID %%p /T >nul 2>&1 REM erase the file ERASE /Q "%_CMDS%" >nul 2>&1 REM check that the file was erased IF EXIST "%_CMDS%" ( CALL :SPEAK "ERASE FILE FAILED" && EXIT /B ) EXIT /B REM ======================================================================================= REM = SPEAK - Speak text REM ======================================================================================= :SPEAK ECHO %~1 EXIT /Bpasindu ~February 4, 2012 @ 11:31 pmhow to program a batch file to start firefox every 5 min??? Jesse~~ ~June 15, 2011 @ 4:17 pmI like your unique scripting method, especially you check for delayed expansion. This could truly help eliminate errors. I have been using this method to nest subroutines and call Multiple subroutines. It is very handy because for the most part I can add the same call modules in every script and call them as needed. For example, sleep.exe is not present on most systems, so the delay you have won't work on every system, and using ping will cause alarms if a good firewall is used, so I call this in most of my scripts and adjust the loops as needed for a timed delay. :Sleep ::~Note: This can create a different delay time if echo is on, creates a much greater delay.~:: set /a cnt=%cnt%+1 if %cnt%==10000 goto :EOF Goto SleepI hope this helps someone! judgedredd ~June 14, 2011 @ 9:12 amHi, I have been searching high and low for a version of this script (which searches all drives for jpg or jpeg files to delete) that deals with finding a file and doing an action if it finds it and doing another action if it does not find it. The script I found that finds the jpg files and finds the drives by using the mountvol code is this: @echo off for /F %%a in ('mountvol ^| find ":"') do ( dir %%a 1>nul 2>nul if not ErrorLevel 1 ( del /s /f %%a*.jpg del /s /f %%a*.jpeg ) )What I want is a variation of this code to do this: @echo off for %%a in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%a:pagefile.sys start VAUTORUN.EXE for %%a in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if not ErrorLevel 1( %%a:pagefile.sys CALL AUTORUN.INF ) EXIT EXITSo you see that in the second example all the drives are written out whereas in the first example they are not. Any ideas on how to incorporate the mountvol code into the second example so that all the drive letters don't have to be written out like inthe first example? AskApache ~April 13, 2011 @ 4:50 am@skoda ~ Originally that was my thought as well and I wanted to do exactly that. The answer is yes it is possible, I am able to get it to work the way you think that it would. But the reality is that it (batch) is extremely poor programming by microsoft, they never intended it to be used by humans I guess.. I had to do a couple hours of trial and error before I finally figured it out.. Actually, figuring out how to do it without looping is similar to debugging mod_rewrite loops, things can really get out of control fast and seemingly without reason when dealing with batch files. @Dylan ~ How about a full-fledged working solution? Please post back if you make any improvements... skoda ~April 6, 2011 @ 10:54 pmI appreciate the effort you have put in presenting a very useful article on writing better batch scripts. Do you know if there is a technique to source (like in unix/linux shells) one batch script in another. I want to put all common functions in one script and then source it in other scripts. These other scripts will call some functions from the sourced script where ever they need them. Dylan ~March 25, 2011 @ 7:34 pmI'd sure like to know how you did the screenshot every 10 minutes script. I've been trying to figure that one out all week, can you give me a clue? WordPress Development / Hosting inSourceCode -------------------------------------------------------------------------------- In the 70s, computer users lost the freedoms to redistribute and change software because they didn't value their freedom. Computer users regained these freedoms in the 80s and 90s because a group of idealists, the GNU Project, believed that freedom is what makes a program better, and were willing to work for what we believed in. -- Richard M. Stallman My Picks Mod_Rewrite Tips and Tricks Crazy Advanced Mod_Rewrite THE Ultimate Htaccess THE Mod_Rewrite Cheatsheet Log Viewing in Console Custom php.ini Tips DNS: Round Robin Speed Fsockopen: PHP Socket-Level Rsync and SSH Transfer -------------------------------------------------------------------------------- Related Articles Custom Webmaster Shell Environment Run Firefox every 5 Min from Windows Batch File Windows Batch Script saves Screenshots every 10min Custom bash_profile for Advanced Shell Users Adding YouTube Videos To Website, 4 Methods Protecting Files with Advanced Mod_Rewrite Anti-Hotlinking PortaPutty Auto-Reconnecting SSH Tunnels on an Encrypted TrueCrypt Portable USB Key w GPG Speed Up Google Analytics, use local ga.js Windows Optimization – Intense Part II Serve External Javascript Files locally for Increased Speed Changing Any Password On XP Wget Trick to Download from Restrictive Sites Newest Posts Install multiple OS Without Cds AskApache Debug Viewer Plugin for WordPress Adding a PayPal Donate Now to Site HOWTO: Uninstall CPANEL over SSH Optimized Vimrc with 256 Colorscheme -------------------------------------------------------------------------------- AskApache ContactAboutSearchSite MapTLDP - DocumentationHtaccess SearchHire AskApacheWireSharkNon-GNUTor ProjectCategories CSSGoogleHackingHostingHtaccessJavascriptLinuxOptimizationPHPSecuritySEOShell ScriptingSoftwareWeb DesignWindowsWordPressOnline Tools .htpasswd file GeneratorBase64 Image ConverterCheck Password StrengthCompress CSSDNS TracerJavaScript Source Code BeautifierMac Address Vendor LookupOnline JavaScript Compressor, Obfuscator, Pretty PrinterP3P Privacy GeneratorRaw HTTP Header DebuggerRequest Method Security ScannerWho Am I – Your IP InformationSearch