Alert if files found in a folder are older than X hours
Moderator: DosItHelp
Alert if files found in a folder are older than X hours
I really liked tips for date and time but I wanted to know if its possible to write a script that can be run to monitor a folder and to generate an alert if files found in the folder are older than X amount of hours rather than amount of days in one of the examples given.
Re: Alert if files found in a folder are older than X hours
Working with DateTime values is terrible in batch. There are no native functions for calculating.
The main problem is that you will find difficult sequences and separators. Ex:
04.01.2010
Tue 01/04/2010
2010-01-04
etc.
I always try to equalize it by reading the "international" settings in the registry (but without guarantee).
If you would like defining a maximum age of hours then you should use minutes for the comparision. The reason why is that batch doesn't know floating point values. 1.9999 is 1 inside a batch environment.
How ever. Try something like that:
Regards
aGerman
The main problem is that you will find difficult sequences and separators. Ex:
04.01.2010
Tue 01/04/2010
2010-01-04
etc.
I always try to equalize it by reading the "international" settings in the registry (but without guarantee).
If you would like defining a maximum age of hours then you should use minutes for the comparision. The reason why is that batch doesn't know floating point values. 1.9999 is 1 inside a batch environment.
How ever. Try something like that:
Code: Select all
@echo off &setlocal
REM folder to be checked
set "Folder=C:\path\to\your\folder"
REM accepted maximum age in minutes
set "MaxAge=60"
REM try to change the working directory
pushd "%Folder%" ||goto :eof
REM read international registry settings
call :GetInternationalSettings DateOrder DateSeparator TimeSeparator
REM get the current number of elapsed minutes since Jan. 1st 1970, 00:00
call :GetNumberOfMinutes %DateOrder% "%DateSeparator%" "%TimeSeparator%" "%date%" "%time%" CurrentMinutes
REM check all files
for /f "delims=" %%a in ('dir /a-d /b') do (
set "filename=%%a "
setlocal enabledelayedexpansion
call :GetNumberOfMinutes %DateOrder% "%DateSeparator%" "%TimeSeparator%" %%~ta FileMinutes
set /a age = CurrentMinutes - FileMinutes
if !age! gtr %MaxAge% (
set /a age /= 60
echo !filename:~,40! -^> older than !age! hours
)
endlocal
)
popd
pause
goto :eof
:GetInternationalSettings
setlocal
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v iDate') do set "iDate=%%a"
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sDate') do set "sDate=%%a"
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sTime') do set "sTime=%%a"
endlocal &set "%~1=%iDate%" &set "%~2=%sDate%" &set "%~3=%sTime%"
goto :eof
:GetNumberOfMinutes
setlocal
set "iDate=%~1" &set "sDate=%~2" &set "sTime=%~3" &set "strDate=%~4" &set "strTime=%~5"
for /f "tokens=2" %%i in ("%strDate%") do set "strDate=%%i"
for /f "tokens=1-4 delims=%sDate%" %%a in ("%strDate%") do (
if %iDate%==0 set /a mm=100%%a %% 100,dd=100%%b %% 100,yy=10000%%c %% 10000
if %iDate%==1 set /a dd=100%%a %% 100,mm=100%%b %% 100,yy=10000%%c %% 10000
if %iDate%==2 set /a yy=10000%%a %% 10000,mm=100%%b %% 100,dd=100%%c %% 100
)
for /f "tokens=1,2 delims=%sTime% " %%a in ("%strTime%") do set /a hh=100%%a %% 100, nn=100%%b %% 100
set /a z=(14-mm)/12,y=yy+4800-z,x=mm+12*z-3,d=153*x+2,d=d/5+dd+y*365+y/4-y/100+y/400-2472633, n=d*1440+hh*60+nn
endlocal &set "%~6=%n%"
goto :eof
Regards
aGerman
Re: Alert if files found in a folder are older than X hours
Not sure what happen to my last reply but here it is again
Thank you for looking at this agerman (after getting a copy of reg.exe from winxp on to this win2k machine the following error came up)
I think this is where it broke due to get a A in the time stamp
As this gives us
and this is the cause of the above error
Thank you for looking at this agerman (after getting a copy of reg.exe from winxp on to this win2k machine the following error came up)
C:\Alert>monitor2
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
STEST.XML -> older than 17559704 hours
I think this is where it broke due to get a A in the time stamp
C:\Alert\Monitor>(
set "filename=STEST.XML "
setlocal enabledelayedexpansion
call :GetNumberOfMinutes 0 "/" ":" 10/24/07 10:43a FileMinutes
set /a age = CurrentMinutes - FileMinutes
if !age! GTR 60 (
set /a age /= 60
echo !filename:~,40! -> older than !age! hours
)
endlocal
)
As this gives us
set /a hh=10010 % 100, nn=10043a % 100
and this is the cause of the above error
Code: Select all
C:\Alert>REM @echo off &setlocal
C:\Alert>REM folder to be checked
C:\Alert>set "Folder=C:\Alert\Monitor\"
C:\Alert>REM accepted maximum age in minutes
C:\Alert>set "MaxAge=60"
C:\Alert>REM try to change the working directory
C:\Alert>pushd "C:\Alert\Monitor\" || goto :eof
C:\Alert\Monitor>REM read international registry settings
C:\Alert\Monitor>call :GetInternationalSettings DateOrder DateSeparator TimeSeparator
C:\Alert\Monitor>setlocal
C:\Alert\Monitor>for /F "tokens=3" %a in ('reg query "HKCU\Control Panel\International" /v iDate') do set "iDate=%a"
C:\Alert\Monitor>set "iDate=VERSION"
C:\Alert\Monitor>set "iDate=0"
C:\Alert\Monitor>for /F "tokens=3" %a in ('reg query "HKCU\Control Panel\International" /v sDate') do set "sDate=%a"
C:\Alert\Monitor>set "sDate=VERSION"
C:\Alert\Monitor>set "sDate=/"
C:\Alert\Monitor>for /F "tokens=3" %a in ('reg query "HKCU\Control Panel\International" /v sTime') do set "sTime=%a"
C:\Alert\Monitor>set "sTime=VERSION"
C:\Alert\Monitor>set "sTime=:"
C:\Alert\Monitor>endlocal & set "DateOrder=0" & set "DateSeparator=/" & set "TimeSeparator=:"
C:\Alert\Monitor>goto :eof
C:\Alert\Monitor>REM get the current number of elapsed minutes since Jan. 1st 1970, 00:00
C:\Alert\Monitor>call :GetNumberOfMinutes 0 "/" ":" "Wed 01/05/2011" "18:09:21.94" CurrentMinutes
C:\Alert\Monitor>setlocal
C:\Alert\Monitor>set "iDate=0" & set "sDate=/" & set "sTime=:" & set "strDate=Wed 01/05/2011" & set "strTime=18:09:21.94"
C:\Alert\Monitor>for /F "tokens=2" %i in ("Wed 01/05/2011") do set "strDate=%i"
C:\Alert\Monitor>set "strDate=01/05/2011"
C:\Alert\Monitor>for /F "tokens=1-4 delims=/" %a in ("01/05/2011") do (
if 0 == 0 set /a mm=100%a % 100,dd=100%b % 100,yy=10000%c % 10000
if 0 == 1 set /a dd=100%a % 100,mm=100%b % 100,yy=10000%c % 10000
if 0 == 2 set /a yy=10000%a % 10000,mm=100%b % 100,dd=100%c % 100
)
C:\Alert\Monitor>(
if 0 == 0 set /a mm=10001 % 100,dd=10005 % 100,yy=100002011 % 10000
if 0 == 1 set /a dd=10001 % 100,mm=10005 % 100,yy=100002011 % 10000
if 0 == 2 set /a yy=1000001 % 10000,mm=10005 % 100,dd=1002011 % 100
)
C:\Alert\Monitor>for /F "tokens=1,2 delims=: " %a in ("18:09:21.94") do set /a hh=100%a % 100, nn=100%b % 100
C:\Alert\Monitor>set /a hh=10018 % 100, nn=10009 % 100
C:\Alert\Monitor>set /a z=(14-mm)/12,y=yy+4800-z,x=mm+12*z-3,d=153*x+2,d=d/5+dd+y*365+y/4-y/100+y/400-2472633, n=d*1440+hh*60+nn
C:\Alert\Monitor>endlocal & set "CurrentMinutes=21570849"
C:\Alert\Monitor>goto :eof
C:\Alert\Monitor>REM check all files
C:\Alert\Monitor>for /F "delims=" %a in ('dir /a-d /b') do (
set "filename=%a "
setlocal enabledelayedexpansion
call :GetNumberOfMinutes 0 "/" ":" %~ta FileMinutes
set /a age = CurrentMinutes - FileMinutes
if !age! GTR 60 (
set /a age /= 60
echo !filename:~,40! -> older than !age! hours
)
endlocal
)
C:\Alert\Monitor>(
set "filename=STEST.XML "
setlocal enabledelayedexpansion
call :GetNumberOfMinutes 0 "/" ":" 10/24/07 10:43a FileMinutes
set /a age = CurrentMinutes - FileMinutes
if !age! GTR 60 (
set /a age /= 60
echo !filename:~,40! -> older than !age! hours
)
endlocal
)
C:\Alert\Monitor>setlocal
C:\Alert\Monitor>set "iDate=0" & set "sDate=/" & set "sTime=:" & set "strDate=10/24/07" & set "strTime=10:43a"
C:\Alert\Monitor>for /F "tokens=2" %i in ("10/24/07") do set "strDate=%i"
C:\Alert\Monitor>for /F "tokens=1-4 delims=/" %a in ("10/24/07") do (
if 0 == 0 set /a mm=100%a % 100,dd=100%b % 100,yy=10000%c % 10000
if 0 == 1 set /a dd=100%a % 100,mm=100%b % 100,yy=10000%c % 10000
if 0 == 2 set /a yy=10000%a % 10000,mm=100%b % 100,dd=100%c % 100
)
C:\Alert\Monitor>(
if 0 == 0 set /a mm=10010 % 100,dd=10024 % 100,yy=1000007 % 10000
if 0 == 1 set /a dd=10010 % 100,mm=10024 % 100,yy=1000007 % 10000
if 0 == 2 set /a yy=1000010 % 10000,mm=10024 % 100,dd=10007 % 100
)
C:\Alert\Monitor>for /F "tokens=1,2 delims=: " %a in ("10:43a") do set /a hh=100%a % 100, nn=100%b % 100
C:\Alert\Monitor>set /a hh=10010 % 100, nn=10043a % 100
C:\Alert\Monitor>set /a z=(14-mm)/12,y=yy+4800-z,x=mm+12*z-3,d=153*x+2,d=d/5+dd+y*365+y/4-y/100+y/400-2472633, n=d*1440+hh*60+nn
C:\Alert\Monitor>endlocal & set "FileMinutes=-1032011400"
C:\Alert\Monitor>goto :eof
STEST.XML -> older than 17559704 hours
C:\Alert\Monitor>popd
C:\Alert>pause
Press any key to continue . . .
C:\Alert>goto :eof
Re: Alert if files found in a folder are older than X hours
I see. While the time in variable %time% comes in 24h format, the time of the FOR loop comes in 12h format and the "a" is for "a.m.".
Could you confirm?
Regards
aGerman
Edit:
Try if this works right.
Could you confirm?
Regards
aGerman
Edit:
Try if this works right.
Code: Select all
@echo off &setlocal
REM folder to be checked
set "Folder=C:\Alert\Monitor"
REM accepted maximum age in minutes
set "MaxAge=60"
pushd "%Folder%" ||goto :eof
call :GetInternationalSettings DateOrder DateSeparator TimeSeparator
call :GetNumberOfMinutes %DateOrder% "%DateSeparator%" "%TimeSeparator%" "%date%" "%time%" CurrentMinutes
for /f "delims=" %%a in ('dir /a-d /b') do (
set "filename=%%a "
setlocal enabledelayedexpansion
call :GetNumberOfMinutes %DateOrder% "%DateSeparator%" "%TimeSeparator%" %%~ta FileMinutes
set /a age=CurrentMinutes - FileMinutes
if !age! gtr %MaxAge% (
set /a age/=60
echo !filename:~,40! -^> older than !age! hours
)
endlocal
)
popd
pause
goto :eof
:GetInternationalSettings
setlocal
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v iDate') do set "iDate=%%a"
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sDate') do set "sDate=%%a"
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sTime') do set "sTime=%%a"
endlocal &set "%~1=%iDate%" &set "%~2=%sDate%" &set "%~3=%sTime%"
goto :eof
:GetNumberOfMinutes
setlocal
set "iDate=%~1" &set "sDate=%~2" &set "sTime=%~3" &set "strDate=%~4" &set "strTime=%~5"
for /f "tokens=2" %%i in ("%strDate%") do set "strDate=%%i"
for /f "tokens=1-4 delims=%sDate%" %%a in ("%strDate%") do (
if %iDate%==0 set /a mm=100%%a %% 100,dd=100%%b %% 100,yy=10000%%c %% 10000
if %iDate%==1 set /a dd=100%%a %% 100,mm=100%%b %% 100,yy=10000%%c %% 10000
if %iDate%==2 set /a yy=10000%%a %% 10000,mm=100%%b %% 100,dd=100%%c %% 100
)
for /f "tokens=1,2 delims=%sTime% " %%a in ("%strTime%") do (set /a hh=100%%a %% 100 &set "nn=%%b")
if "%nn:~-1%" equ "p" if "%hh%" neq "12" set /a hh+=12
if "%nn:~-1%" equ "a" if "%hh%" equ "12" set /a hh=0
for /f "delims=ap" %%a in ("%nn%") do set /a nn=100%%a %% 100
set /a z=(14-mm)/12,y=yy+4800-z,x=mm+12*z-3,d=153*x+2,d=d/5+dd+y*365+y/4-y/100+y/400-2472633,n=d*1440+hh*60+nn
endlocal &set "%~6=%n%"
goto :eof
Re: Alert if files found in a folder are older than X hours
Thanks for the help aGerman, yes its funny that the files have a or p on them. I think this is a feature of windows 2000 on windows 7 it shows as either AM or PM
The code runs but not sure as expected
Here is the file listing
And the result from the batch file
The code runs but not sure as expected
Here is the file listing
Code: Select all
Directory of C:\Alert\Monitor
01/06/2011 12:41p 0 file1.txt
10/24/2007 10:43a 514 file2.txt
And the result from the batch file
Code: Select all
C:\Alert>monitortest.bat
file1.txt -> older than 17531640 hours
file2.txt -> older than 17559722 hours
Press any key to continue . . .
-
- Posts: 319
- Joined: 12 May 2006 01:13
Re: Alert if files found in a folder are older than X hours
JohnDoe wrote:I really liked tips for date and time but I wanted to know if its possible to write a script that can be run to monitor a folder and to generate an alert if files found in the folder are older than X amount of hours rather than amount of days in one of the examples given.
download findutils for windows, then use this one liner to find files older than 1 hr ago
Code: Select all
c:\test> gnu_find.exe c:\directory -type f -mmin +60
if there are output displayed, then you can do the alert.
Its certainly easier than to maintain a whole bunch of inefficient DOS batch commands that mess around with registry. Alternatively, if you can't download stuff, using vbscript is still better than batch, since it can do Date maths pretty easily.
Re: Alert if files found in a folder are older than X hours
I'm at my wits end. It's like I wrote in my first post: "Working with DateTime values is terrible in batch."
I agree with ghostmachine4.
Regards
aGerman
I agree with ghostmachine4.
Regards
aGerman
Re: Alert if files found in a folder are older than X hours
aGerman i completely agree about times in windows there always seems to be not set standard of how time stamps are shown.
ghostmachine4 thanks for the link I will download and have a play with it.
ghostmachine4 thanks for the link I will download and have a play with it.
Re: Alert if files found in a folder are older than X hours
Well this is what I have so far please let me know what you think.
I could not get any error levels from the gnu find so I had to pump the output to findstr
ghostmachine4 Is there any way with gnu_find to find files with a certain extension, as well as not to search sub folders ?
I could not get any error levels from the gnu find so I had to pump the output to findstr
Code: Select all
@echo off &setlocal
gnu_find C:\Alert\Monitor -type f -mmin +60 | findstr "txt" >nul && goto foundfiles
echo. All is good go back to sleep
goto exit
:foundfiles
echo. Alert ! Alert! we found files
:exit
ghostmachine4 Is there any way with gnu_find to find files with a certain extension, as well as not to search sub folders ?
Re: Alert if files found in a folder are older than X hours
Ok here is the near final code.
We have an application that picks up files from a certain folder, every now and again a file will come in corrupt as such it will block the application and it will not pickup any of the other files.
I hope to have created this workaround script to check for files in the folder and if they are older than a hour then it will move and rename the oldest file in hope of finding the corrupt file and alert the helpdesk.
Please let me know what you think I am sure there might be some better ways of doing some of these things
We have an application that picks up files from a certain folder, every now and again a file will come in corrupt as such it will block the application and it will not pickup any of the other files.
I hope to have created this workaround script to check for files in the folder and if they are older than a hour then it will move and rename the oldest file in hope of finding the corrupt file and alert the helpdesk.
Please let me know what you think I am sure there might be some better ways of doing some of these things
Code: Select all
@echo off &setlocal
cls
REM folder to be checked
set "CheckFolder=C:\Alert\Monitor"
set "MoveFolder=C:\Alert\bad"
set "MaxAge=60"
REM Find and check for any files that might be suck in the inbound message folder.
gnu_find %CheckFolder% -maxdepth 1 -type f -name *TCLMD* -mmin +%MaxAge% | findstr ".mq" >nul && goto FindOldest
echo.&echo.&echo.
echo. No Files found over %MaxAge% minutes so we can go back to sleep
wait 5
goto Exit
:FindOldest
Rem Find the oldest file as this file might be a corrupt message and the reason for the router failing to pickup these messages.
for /f "tokens=*" %%D in ('dir %CheckFolder%\*.MQ /A-D /B /O-D') do set OldestMsg=%%D
echo.&echo.&echo.
echo The oldest message found in %CheckFolder% is %OldestMsg%
echo.
Rem Generate a random number based on the date so we can use it to rename the file.
for /f "tokens=2-8 delims=/:. " %%A in ("%date%:%time: =0%") do set "UNIQUE=%%C%%A%%B%%D%%E%%F%%G"
Rem Lets rename and move the file so it is not picked up again and allow the router to move on and we hope pickup the other messages.
echo.&echo.&echo.
echo Moving %CheckFolder%\%OldestMsg% to %MoveFolder%\%UNIQUE%.badsms
move "%CheckFolder%\%OldestMsg%" %MoveFolder%\%UNIQUE%.badsms
echo.
goto :SendAlert
Rem We had better let the Helpdesk know.
:SendAlert
ECHO.
ECHO Sending an Alert to let the Helpdesk know
ECHO.
set AlertTime=%Time:~0,5% %Date:~4,6%%Date:~-2%
sendemail -s 127.0.0.1:25 -o message-header="X-Priority: 1" -f italert@domain.com -t helpdesk@domain.com -u "There Appears to be a stuck message on %computername%" at %Time:~0,5% -m "Warning a message on %computername% was blocking the inbound router. It generated this alarm at %AlertTime% "\n""\n" A copy of the offending message has been attached to this message. Please take a look at the file most messages fail due to a Alpha from field or a funny character in the body of the message. "\n""\n" If you want to try and process the message again copy '%MoveFolder%\%UNIQUE%.badsms' into %Foldercheck%" -a "%MoveFolder%\%UNIQUE%.badsms"
echo.
echo Alert Sent we are all done Time to Zzzzzzzzz.
Rem Clean up environment space
set "CheckFolder="
set "MoveFolder="
set "MaxAge="
set "OldestMsg="
set "UNIQUE="
set "AlertTime="
wait 5
goto Exit