1

here is what i'm trying to do:

Use the forfiles Command in a .cmd script to delete folders from a specified path that are older than e. g. 2 days on a win7 machine.

Edit: The Situation is the following under the path X:\backups are folders which contain daily backups e. g. 25.06.2014 next folder 24.06.2014 and so on.

My questions regarding this are now:

  • /d in the help it always stresses --files--. So I'm not sure if this works for folders too.
  • especially i'm not sure what it would do in combination with /s. So it would just run through the folders and delete the files - but what if already the parentfolder was too old? On a sidenote the whole concept of recursive is not clear to me and what it means i was not able to find out. It just means going through the folders right?
  • If i would go with an IF-Statement then i would have to use 2 Variable @ISDIR and @FDATE. With this solution i don't know how to combine 2 If-Statements in the forfiles command and additionally i'm not sure if @FDATE is again only for files and not folders.

So how to do it right?

Reference of forfiles: http://technet.microsoft.com/de-de/library/cc753551%28v=ws.10%29.aspx

Greetings!

1
  • Is using PowerShell an option? Jun 24, 2014 at 17:45

4 Answers 4

6

Solution

Despite its name, the forfiles command is able to handle both files and folders. Here's a batch script that does the job:

@echo off
setlocal

set target=X:\backups
set days=-2

for /f "usebackq delims=" %%G in (
`forfiles /p "%target%" /c "cmd /c if /i @isdir == true echo @path" /d %days% 2^>nul`
) do echo rd /s /q "%%~G"

pause
endlocal & exit /b

How it works

First of all, the target and days variables are initialized. The first one is set to the folder you want to scan, and the latter is the amount of days. Negative values mean older than or equal.

The forfiles command is then run by specifying the folder and number of days that were set earlier. For each result, the special @isdir variable is checked: if the value is true the current entry is a folder, and its @path is echoed. The command output is then parsed to get all matching folders and delete them. For safety reasons, there's an extra echo command so you can check whether the right folders are removed.

When using the recursive switch (/s), all files, folders, and their subfolders are processed. In this case you don't want to; otherwise you might end up deleting old subfolders contained in newer folders, which shouldn't be touched at all.

Further reading

5
  • Thx for the answer but i'm having trouble to understand:
    – user54512
    Jul 3, 2014 at 7:10
  • O.k. "Enter" leads to posting and "you are only allowed to edit for 5 minutes" so here is the actual post: Thx for the answer. Despite Googling i'm having trouble to understand: 1).. "usebackq delims=" %%G in.. - what does this line do? 2) What is the ` for? 3)It seems that you have an outside for loop in which the forfiles command runs. Isn't that what forfiles already does?
    – user54512
    Jul 3, 2014 at 7:39
  • 1
    @user54512 The syntax is for /f "<options>" <variable> in (<input>) do <whatever>. The usebackq option enables the use of quotes for paths/file names (quotes are used to denote strings otherwise), and backticks for commands. The default delimiters are space chars and tabs; delims= clears them, to avoid breaking paths containing spaces. In this specific case you could just use this: forfiles /p "X:\backups" /c "cmd /c if /i @isdir == true echo rd /s /q @path" /d -2 By wrapping it in an extra for loop you get a more flexible solution should you need to run more than a single command.
    – and31415
    Jul 3, 2014 at 14:43
  • Note that TRUE and FALSE values must be UPPERCASE in some Windows versions, including my copies of Windows 7 and 2008 R2.
    – Paul
    Nov 9, 2015 at 17:54
  • Excellent answer, exactly what I was looking for. Works like a charm !
    – robe007
    Sep 27, 2018 at 22:10
1

The one-line PowerShell doesn't quite get you there. It does not include the full path to the list of files. Also, you may need to recurse. This works:


get-childitem "D:\backup" |? {$.psiscontainer -and $.lastwritetime -le (get-date).adddays(-0)} |% {remove-item D:\backup\$_ -force -recurse -whatif}


0
0

Here is a one-line PowerShell approach:

get-childitem "x:\backups" |? {$_.psiscontainer -and $_.lastwritetime -le (get-date).adddays(-2)} |% {remove-item $_ -force -whatif}

You can adjust the age threshold through the adddays' parameter. This is still in "WhatIf" mode, so you can test it first and see what would happen. Remove the -whatif to make it actually delete the folders.

Source: TechNet Forum

1
  • Thanks but using Powershell is not possible. I would need it in a .bat or .cmd file
    – user54512
    Jun 25, 2014 at 7:11
0

how it should work on WIndows server 2019? I think " `" have problem on new OS

@echo off
setlocal

set target=X:\backups
set days=-2

for /f "usebackq delims=" %%G in (
`forfiles /p "%target%" /c "cmd /c if /i @isdir == true echo @path" /d %days% 2^>nul`
) do echo rd /s /q "%%~G"

pause
endlocal & exit /b

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .