# Solved: Batch File to delete old Folders...



## kenne75 (Aug 3, 2009)

My helpdesk software is writing a backup file to a directory I created on the hard drive. It creates a new directory every night at midnight, it only stores 7 nights worth so I have a directory call C:\Backup with 7 folders in there being named 1-7. I need some help creating a batch file that will only keep the 2 newest folders as it is taking up to much space on the Server. If it makes a difference I am running Windows Server 2003. Any help would be greatly appreciated. Help me Please!

Here is the Batch I have created but for some reason isn't working. I get the prompt but when I say A for all the directory still exists. 

:: User Variables
:: Set this to the number of folders you want to keep
Set _NumtoKeep=1
:: Set this to the folder that contains the folders to check and delete
Set _Path=C:\Program Files\SysAidServer\backup
If Exist "%temp%\tf}1{" Del "%temp%\tf}1{"
PushD %_Path%
Set _s=%_NumtoKeep%
If %_NumtoKeep%==1 set _s=single
Echo Please wait, searching for folders other than the %_s% most recent
For /F "tokens=* skip=%_NumtoKeep%" %%I In ('dir "%_Path%" /AD /B /O-D /TW') Do (
If Exist "%temp%\tf}1{" (
Echo %%I:%%~fI >>"%temp%\tf}1{"
) Else (
Echo.>"%temp%\tf}1{"
Echo Do you wish to delete the following folders?>>"%temp%\tf}1{"
Echo Date Name>>"%temp%\tf}1{"
Echo %%I:%%~fI >>"%temp%\tf}1{"
))
PopD
If Not Exist "%temp%\tf}1{" Echo No Folders Found to delete & Goto _Done
Type "%temp%\tf}1{" | More
Set _rdflag= /q
:_Prompt1
Set /P _resp=Delete All, None, or Prompt for each (A/N/P)?
If /I "%_resp:~0,1%"=="N" Goto _Done
If /I "%_resp:~0,1%"=="A" Goto _Removeold
If /I NOT "%_resp:~0,1%"=="P" (Echo (A/N/P only please)&Goto _Prompt1
Set _rdflag=
:_Removeold
For /F "tokens=1* skip=3 Delims=:" %%I In ('type "%temp%\tf}1{"') Do (
If "%_rdflag%"=="" Echo Deleting
rd /s%_rdflag% "%%J")
:_Done
If Exist "%temp%\tf}1{" Del "%temp%\tf}1{"
HTH


----------



## TheOutcaste (Aug 8, 2007)

I would think the helpdesk software would have a setting to control how many days of backups to keep. If so, that would be the easiest way to manage this.


kenne75 said:


> I have a directory call C:\Backup with 7 folders in there being named 1-7.


If the root folder is *C:\Backup* then the *Set _Path=* statement should be 
* Set _Path=C:\Backup*
not
*Set _Path=C:\Program Files\SysAidServer\backup*


kenne75 said:


> I need some help creating a batch file that will only keep the 2 newest folders


_NumtoKeep should be set to two, not one if you want to keep the two newest folders


kenne75 said:


> I get the prompt but when I say A for all the directory still exists.


You are checking the *C:\Program Files\SysAidServer\backup* folder and not *C:\Backup*, correct?
If folders are created in date order from 1-7, when you run this it lists 1-6? Does it show the full path, which with the code you posted should be:
*C:\Program Files\SysAidServer\backup\1* and so on
After entering *A* to delete all, does it show any errors?
If you immediately run it again, does it still list the same 6 folders, or say there are no folders to delete?
Have you tried using *P* to prompt for each folder?

I have not had any problems with this code. I've run it on several test trees, and it always deletes all but the newest folder (with _NumtoKeep set to 1), and can't see where any thing has been changed from the original code I posted.

I have cleaned it up a bit; as this was extracted from a routine that deleted by date it still had the date header, but outputs the folder name as the date.
The following should look a little cleaner.

```
@Echo Off
:: User Variables
:: Set this to the number of folders you want to keep
Set _NumtoKeep=1
:: Set this to the folder that contains the folders to check and delete
Set _Path=C:\Backup
If Exist "%temp%\tf}1{" Del "%temp%\tf}1{"
PushD %_Path%
Set _s=%_NumtoKeep%
If %_NumtoKeep%==1 set _s=single
Echo Please wait, searching for folders other than the %_s% most recent
For /F "tokens=* skip=%_NumtoKeep%" %%I In ('dir "%_Path%" /AD /B /O-D /TW') Do (
  If Exist "%temp%\tf}1{" (
    Echo %%~fI>>"%temp%\tf}1{"
  ) Else (
    Echo.>"%temp%\tf}1{"
    Echo Do you wish to delete the following folders?>>"%temp%\tf}1{"
    Echo Name>>"%temp%\tf}1{"
    Echo %%~fI>>"%temp%\tf}1{"
    ))
PopD
If Not Exist "%temp%\tf}1{" Echo No Folders Found to delete & Goto _Done
Type "%temp%\tf}1{" | More
Set _rdflag= /q
:_Prompt1
Set /P _resp=Delete All, None, or Prompt for each (A/N/P)?
If /I "%_resp:~0,1%"=="N" Goto _Done
If /I "%_resp:~0,1%"=="A" Goto _Removeold
If /I NOT "%_resp:~0,1%"=="P" (Echo A/N/P only please)&Goto _Prompt1
Set _rdflag=
:_Removeold
For /F "tokens=1* skip=3 Delims=:" %%I In ('type "%temp%\tf}1{"') Do (
 If "%_rdflag%"=="" Echo Deleting
 rd /s%_rdflag% "%%J")
:_Done
If Exist "%temp%\tf}1{" Del "%temp%\tf}1{"
```


----------



## kenne75 (Aug 3, 2009)

Alright, I guess I am going to try to explain this a little better for you and I appreciate you assistance. There isn't a setting in the help desk software but I have made the company aware that it would be a great feature to have. I would prefer to do a delete of the directories that are older then 2 days, and the directory I am working in is C:\Program Files\SysAidServer\backup. Also, wondering if you could show me how I could make it so I am not prompted, so that it just deletes the folders and all their contents that are older then 2 days. I would like to set this batch file up in a scheduled task to run nightly. I appreciate any help.


----------



## TheOutcaste (Aug 8, 2007)

This version deletes all but the 2 newest folders, regardless of date, so if you create 5 folders _today_, it would delete all but the two newest. It does not display anything on screen, just deletes all the folders found:

```
@Echo Off
:: User Variables
:: Set this to the number of folders you want to keep
Set _NumtoKeep=2
:: Set this to the folder that contains the folders to check and delete
Set _Path=C:\Program Files\SysAidServer\backup
PushD %_Path%
For /F "tokens=* skip=%_NumtoKeep%" %%I In ('dir "%_Path%" /AD /B /O-D /TW') Do rd /s /q "%%~fI"
PopD
```
This version will check the actual date the folders were last modified, and delete all but the last two days, not counting today. So if you run it on 8/3, it will delete folders that were modified on 7/31 and earlier, keeping those modified on 8/1, 8/2, and 8/3. If you create 5 folders on 8/1, 8/2, and 8/3, this will keep all 15 folders

```
@Echo Off
Setlocal EnableDelayedExpansion
:: User Variables
:: Set this to the number of days you want to keep
Set _DaysKept=2
:: Set this to the folder that contains the folders to check and delete
Set _Path=C:\Program Files\SysAidServer\backup
:: Get todays date
Call :GetDate
Set _yy=%_fDate:~,4%
Set _mm=%_fDate:~4,2%
Set _dd=%_fDate:~6,2%
:: Convert todays date to Julian
Call :JDate %_yy% %_mm% %_dd%
Set _JToday=%_JDate%
:: Set delete date
Set /a _DelDate=_JToday-%_DaysKept%-1
:: Get time format, _iTime will be 0 if 12 hour clock, 1 if 24 hour clock
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iTime') Do Set _iTime=%%B
PushD %_Path%
If %_iTime%==0 (Set _Tok=1,4*) Else (Set _Tok=1,3*)
For /F "tokens=%_Tok% skip=4" %%I In ('dir "%_Path%" /AD /OD /TW') Do (
Set _Name=%%K
  If NOT "%%K"=="." If NOT "%%K"==".." If %%J==^<DIR^> (
    Call :GetDate %%I
    Call :JDate !_fDate:~,4! !_fDate:~4,2! !_fDate:~6,2!
    If !_JDate! LEQ %_DelDate% (
      rd /s /q "%%~fK"
      ) Else (
      Goto :_allFound
      )))
:_allFound
PopD
Goto:EOF
::===================================::
::                                         ::
::   -   S u b r o u t i n e s   -   ::
::                                         ::
::===================================::
:JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date in variable _JDate
:: Usage
::Call :JDate %__GYear% %_GMonth% %_GDay%
:: First strip leading zeroes; a logical error in this
:: routine was corrected with help from Alexander Shapiro
::Code taken from datediff.bat written by Rob van der Woude
::http://www.robvanderwoude.com
Set _JMM=%2
Set _JDD=%3
IF 1%_JMM% LSS 110 Set _JMM=%_JMM:~1%
IF 1%_JDD% LSS 110 Set _JDD=%_JDD:~1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
Set /A _JMonth1 = ( %_JMM% - 14 ) / 12
Set /A _JYear1  = %1 + 4800
Set /A _JDate  = 1461 * ( %_JYear1% + %_JMonth1% ) / 4 + 367 * ( %_JMM% - 2 -12 * %_JMonth1% ) / 12 - ( 3 * ( ( %_JYear1% + %_JMonth1% + 100 ) / 100 ) ) / 4 + %_JDD% - 32075
For %%A In (_JMonth1 _JYear1) Do Set %%A=
Goto:EOF
:GetDate
:: This subroutine will always display the same results,
:: for the date independent of "International" settings.
:: This batch file uses REG.EXE from the NT Resource Kit
:: (already installed with WinXP and Vista)
:: to read the "International" settings from the registry.
:: Date is returned as yyyymmdd in variable _fdate
:: Modified from SortDate Written by Rob van der Woude
:: http://www.robvanderwoude.com
::
If NOT [%1]==[] Set Date=%1
If "%date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Using default delimiters of Tab and Space
For /F "SKIP=3 TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "SKIP=3 TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%date%") Do Set _fdate=%%D%%B%%C
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%date%") Do Set _fdate=%%D%%C%%B
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%date%") Do Set _fdate=%%B%%C%%D
Goto:EOF
```


----------



## kenne75 (Aug 3, 2009)

Thank you, I ran with the first one and it worked great.


----------

