• How to use a Windows .bat file to delete files on a schedule

    This is how you delete files of a certain age using a scheduled task to execute a .bat file. These instructions mainly apply to Windows Server 2012 R2, but they are applicable to most newer (and older) versions of Windows. This is similar to the post I made many years ago but with some additions mainly around the commands you need to find files that are older than a certain date and then deleting them. It also focuses on Server 2012 R2 versus the older 2008.

    The first thing we want to do is create the batch file that we will use to delete the files older than X days. To do this we will need to use the forfiles command in Windows. This is a very handy command for batch files IMO. Here is a run down of the forfiles command and how to use it:




    Usage:
    FORFILES [/P pathname] [/M searchmask] [/S] [/C command] [/D [+ | -] {MM/dd/yyyy | dd}]

    Description: Selects a file (or set of files) and executes a command on that file. This is helpful for batch jobs.

    Parameter List:
    /P – Pathname – Indicates the path to start searching. The default folder is the current working directory (.).

    /M – searchMask – Searches files according to a searchmask. The default searchmask is ‘*’ .

    /S – Subdirectories – Instructs forfiles to recurse into subdirectories. Like “DIR /S”.

    /C – Command – Indicates the command to execute for each file. Command strings should be wrapped in double quotes.

    You can use these VARIABLES in the Command (/C) string:
    @file – returns the name of the file.
    @fname – returns the file name without extension.
    @ext – returns only the extension of the file.
    @path – returns the full path of the file.
    @relpath – returns the relative path of the file.
    @isdir – returns “TRUE” if a file type is a directory, and “FALSE” for files.
    @fsize – returns the size of the file in bytes.
    @fdate – returns the last modified date of the file.
    @ftime – returns the last modified time of the file.

    To include special characters in the command line, use the hexadecimal code for the character in 0xHH format (ex. 0x09 for tab). Internal CMD.exe commands should be preceded with “cmd /c”.

    /D – Date – Selects files with a last modified date greater than or equal to (+), or less than or equal to (-), the specified date using the “MM/dd/yyyy” format; or selects files with a last modified date greater than or equal to (+) the current date plus “dd” days, or less than or equal to (-) the current date minus “dd” days. A valid “dd” number of days can be any number in the range of 0 – 32768. “+” is taken as default sign if not specified.





    To make our scheduled task delete all files older than 7 days, we create the .bat file with the following command:

    
    forfiles /P "YOUR_DRIVE:\YOUR_FOLDERS" /S /M *.* /D -8 /C "cmd /c del @FILE"
    

    So what exactly is this command doing:
    1. It is looking at the /P (pathname parameter) for the location you want to run the command on. Be sure to change this to yours, d’uh!
    2. /S – we want to check if there are any subdirectories as well.
    3. /M – we want to match everything as this is just a backup folder, hence *.*.
    4. /D – since we want to keep 7 days worth, we delete anything 8 days or older.
    5. /C – this is the command we want to run against the files returned by forfiles. We want to run Delete (del) against all files found by forfiles in this case.

    On older systems, you may have to switch / for – but in newer systems it is somewhat interchangeable but other OS’s may complain about quotes so it might take some fiddling. For example this would work too on 2012 R2:

    
    forfiles -p "YOUR_DRIVE:\YOUR_FOLDERS" -s -m *.* /D -8 /C "cmd /c del @FILE"
    

    Now that you have your .bat created, save it somewhere and be sure to name it with the .bat extension when you save, again duh. Although you can always change it after if you have file extensions on. Make sure you TEST it as well. I like to test my forfiles command first before I have it run any other commands just to make sure it is finding the correct files (so I don’t delete the wrong things accidentally).

    When you are comfortable with your batch file, launch the taskscheduler from the administrative tools, and create task. You can choose Create Basic if you wish, but this is just based on create task alone.




    On the first screen give it a name and you can select/configure the user and environment (we changed environment to Windows Server 2012 R2). Make sure the user you use has permission to run the task when not logged in if that is what you want to do.

    On the next tab you will set the trigger, no point running this more than once per day as it searches for items older than 8. I like to set this for once per week, so we effectively have 14 backups when the scheduled task runs to delete the previous weeks backups to make room for the upcoming weeks backups.

    The next tab allows you to setup the action. Choose start a program, then under program/script open browse to your windows/system32 folder and select the cmd.exe program.

    You now need to add the arguments, they are as follows:

    
    /q /c "DRIVE:\PATH\TO\yourbatchfile.bat"
    

    /q is to suppress anything on the screen.
    /c is used to start a new instance of the batch script.

    Now click okay, you will be prompted for your password at this point, enter it then you are finished.

    Here is an XML file you can use that runs your .bat file weekly, just modify it for your settings then import it:



    
    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
      <RegistrationInfo>
        <Date>2017-03-16T11:11:48.2350658</Date>
        <Author>COMPUTERPLUMBER</Author>
      </RegistrationInfo>
      <Triggers>
        <CalendarTrigger>
          <StartBoundary>2017-03-16T11:15:44</StartBoundary>
          <Enabled>true</Enabled>
          <ScheduleByWeek>
            <DaysOfWeek>
              <Sunday />
            </DaysOfWeek>
            <WeeksInterval>1</WeeksInterval>
          </ScheduleByWeek>
        </CalendarTrigger>
      </Triggers>
      <Principals>
        <Principal id="Author">
          <UserId>YOURCOMPUTER\YOURUSER</UserId>
          <LogonType>Password</LogonType>
          <RunLevel>LeastPrivilege</RunLevel>
        </Principal>
      </Principals>
      <Settings>
        <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>false</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
          <StopOnIdleEnd>true</StopOnIdleEnd>
          <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>true</Enabled>
        <Hidden>false</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
        <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
        <WakeToRun>false</WakeToRun>
        <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
        <Priority>7</Priority>
      </Settings>
      <Actions Context="Author">
        <Exec>
          <Command>C:\Windows\System32\cmd.exe</Command>
          <Arguments>/q /c "DRIVE:\PATH\TO\yourbatchfile.bat"</Arguments>
        </Exec>
      </Actions>
    </Task>
    




    Share

    Leave a reply