Task to delete a directory runs with success but the directory is still there

batch-filetask-schedulerwindows-server-2012

I have a task in the task scheduler on a Windows 2012 file server. The task has to delete the contents of a temporary general access directory every Sunday night. It runs at the scheduled times and reports success each time but the directory contents aren't being deleted.

The task includes this batch file:

D:  
cd D:\Shared\Temp\  
del /Q /F /S "D:\Shared\Temp\*.*"

This is the task's xml:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2014-06-16T12:13:45.8524361</Date>
    <Author>OFFICE\Administrator</Author>
    <Description>Weekly deletes the contents of the Temp directory</Description>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2014-06-22T20:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Sunday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>OFFICE\Administrator</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>false</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>true</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"D:\IT\tempdelete.bat"</Command>
    </Exec>
  </Actions>
</Task>

I can't understand why this task doesn't do what it's supposed to do. Could someone with more experience shed some light on this?

Update 11 August 2014

There was another answer here which suggested the following edit in my batch command (I don't know why it has been deleted):

D:
cd D:\Shared\Temp\
del /F /S "D:\Shared\Temp\*.*" 1> D:\my.log 2>&1

This weekend I ran this script. The Task Scheduler is still claiming that the job finished with success but this time I have a contradictory my.log file:

The system cannot find the path specified.

I cannot see a path definition error in my script. The specified path is correct.

Should I not change the directory as joeqwerty states?
or
Should I define the directory change in brackets, too?
or what???

Best Answer

I can think of two possibilities.

1) The files are being added after your scheduled task completes. But I suspect you are checking the timestamps and seeing dates that predate the task. So this is probably not the problem.

2) One or more files may be locked by another process, which would prevent deletion.

Unfortunately the DEL command does not return an errorcode if it fails. It prints an error message to stderr, but the returned ERRORLEVEL is always 0.

You can confirm that locked files are causing the problem by redirecting stderr for your DEL command to a file using 2>somePath\someFile.log. When there has been a failure, you should see an error message like The process cannot access the file because it is being used by another process. in the log file.

If you want to detect and take action if one or more files are locked, then you could use a variant of How to stop batch script on del failure.

set "locked="
for /r "D:\Shared\Temp" %%F in (.) do dir /a-d "%F" >nul 2>nul && (ren "%F\*" * || set locked=1)
if defined locked echo Take some action because files are locked.

Renaming files to their original name will fail if one or more files are locked. But you shouldn't do the test if there are no files in a given folder. The DIR /A-D command detects if a given folder contains files. The FOR /R command iterates all the folders, including the specified root.

EDIT

I should have read that link I cited further. Toward the bottom are answers that give a more direct way of detecting failed deletion, without using an extra command to detect open files. Simply examine the stderr output of the DEL command. Doh!

del /Q /F /S "D:\Shared\Temp\*.*" 2>&1 1>nul | findstr "^" >nul && echo Take action because one or more files were locked and could not be deleted

This solution is better because it is detecting the error of DEL directly. Looking for locked files as a separate command could fail if the file is locked after the lock check, but before the delete.

Related Topic