batch - execute command for every file with specific creation date - windows

got this piece of code:
forfiles /P %ParentFolder% /S /M %Format% /C "cmd /c %exeFile% #path"
executing some exe for every file matching format as parameter.
any way to add "creation date" as a condition to run command via CMD?
something like :
for all files in directory (recursive) X if creation date newer then 1 day ago do (run) some exe with this file's path as param

This is not possible with forfiles, because, when the /D option is provided, it only regards the last modification date only (not even the modification time).
Unfortunately, there are no native commands for date/time maths, so I suggest to switch to a language that is capable of that; for instance, PowerShell, VBScript, JavaScript (which are all native to Windows past XP).
In case the modification date could be used, and a simple check with the date of today is sufficient, the following forfiles command line could be used:
forfiles /S /P "%ParentFolder%" /M "%Format%" /D +0 /C "cmd /C \"%exeFile%\" #path"
The /D option with a non-negative number lets forfiles return files that have been modified the given number of days after today or later (although you would need a time-machine; hence I consider this a design flaw). For +0 as the given number of days, all matching files modified today are returned, because forfiles /D only checks the modification date but does not care about the modification time.
If a simple equality check of the creation date with the date of today is fine for you, it can be done in batch-file scripting quite easily though (see all the explanatory rem remarks for how the following script works):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "ParentFolder=."
set "Format=*.*"
set "exeFile=" & rem // (full path to executable file)
set "tmpFile=%TEMP%\%~n0_%RANDOM%.tmp"
rem // Create a temporary file and retrieve its creation date:
2> nul del "%tmpFile%" & > "%tmpFile%" break & set "TODAY="
for /F "skip=5" %%J in ('dir /N /4 /-C /T:C "%tmpFile%"') do (
if not defined TODAY set "TODAY=%%J" & del "%tmpFile%"
)
rem // Change to predefined parent directory:
pushd "%ParentFolder%" && (
rem // Return all files recursively:
for /F "delims=" %%I in ('dir /B /S /A:-D "%Format%"') do (
rem // Determine the creation date for the current file:
set "FIRST=#"
for /F "skip=5" %%J in ('dir /N /-C /T:C "%%I"') do (
rem // Regard line listing file only, ignore summary lines:
if defined FIRST (
set "FIRST="
rem // Check creation date against today:
if "%%J"=="%TODAY%" (
rem // Return files created today:
echo "%%I" has been created today.
rem // Run external program on found file:
if defined exeFile "%exeFile%" "%%I"
)
)
)
)
rem // Restore previous working directory:
popd
)
endlocal
exit /B
I am using two dir command lines here:
the first one returns a bare list of files recursively (/S; no directories because of /A:-D) without any dates/times, headers and footers, due to switch /B; not using this switch would lead to header and footer lines for the whole output and for every iterated sub-directory also, so the output would be quite complicated to be parsed;
the second one receives each file returned by the first one; since there is no /B but the /N option, the file creation date/time is returned (/T:C); for every file the output looks like this:
Volume in drive D is DATA
Volume Serial Number is 0000-0000
Directory of D:\Data
2016/09/29 16:00 1024 current_file.txt
1 File(s) 1024 bytes
0 Dir(s) 1099511623680 bytes free
the first token of the sixth line constituting the creation date is split off and compared against the current date %DATE%; to ignore the header, the skip=5 option of the for /F loop is used; to ignore the summary lines, the variable FIRST is used;
Note that the date format is locale-dependent; as long as there appear no spaces in the date, this is no problem as the current date is also determined by the dir command applied on a temporary file.

Looking at the forfiles /? shows the switch /D that will exclude files that are younger (/d -<days>) or older (/d +<days>) than the given value for <days>.
As you want the files from today, you would set <date> to 0.
Notice, that this will look on the changed date!
Other way would be to use a for /r-loop and get a list of the creation date with dir /T:C ; to sort it add /O-D. Then separate that using a for /f loop to get the lines of the output of dir and another one to separate it (possibly easier without the nested loops).
You can than compare the creation date with %date% or when using one day=24 hrs compare the creation time with %time% additionally.

Related

Searching for partial path\filename in bat

Ok, so I've been bating (hehe) my head against a wall here.
I am looking for an option/code that would allow me to search for a partial path and/or filename from a .bat script that I would export to an outside file.
Now, "search", "export" and "outside file" is something I am fine with. The part that is giving me a headache is the "partial".
To elaborate.
I am looking for a folder called DATA and a file called userinfo.txt inside DATA.
Those are constant. So the path I have is DATA\userinfo.txt
I am also 99% certain that this folder will be in D:\ but thats not a concern right now. Where ever it is I'll find it.
But I cannot figure out how to look for a partial path\filename for the life of me.
Reason I have specified that DATA\userinfo.txt is a constant is due to other folders ability to be named arbitrarily. So in my below example 01-12-2016 does not have to be named according to that convention. For USA it would most likely be named 12-01-2016. It is also sometimes named 20161201 or 20160112 or on top of all that has a letter prefix such as d01-12-2016. On that note DATA is always DATA, which is why I said DATA is constant in my search. Another thing that will be the same is the grandparent folder. When i say "same" i mean "shared" between the two applications. It does not mean it will always be named "program" as in my example below.
Googling this and using things I know has got me nowhere.
Reason I cannot simply use
where /r d: userinfo.txt
is that that specific command will return hundreds of results as there is a userinfo.txt created for every.single.day the program was running and is stored separately.
Alternatively - if there would be a way to comb trough those hundreds of results and find the matching part that would also resolve my issue.
This however brings up another headache as there is usually more than one program with this exact file.
so in the example of
d:\users\path\program\storage\01-12-2016\userinfo.txt
d:\users\path\program\otherstorage\01-12-2016\userinfo.txt
d:\users\path\program\storage\02-12-2016\userinfo.txt
d:\users\path\program\otherstorage\02-12-2016\userinfo.txt
d:\users\path\program\storage\03-12-2016\userinfo.txt
d:\users\path\program\otherstorage\03-12-2016\userinfo.txt
d:\users\path\program\storage\04-12-2016\userinfo.txt
d:\users\path\program\otherstorage\04-12-2016\userinfo.txt
d:\users\path\program\storage\05-12-2016\userinfo.txt
d:\users\path\program\otherstorage\05-12-2016\userinfo.txt
d:\users\path\program\storage\06-12-2016\userinfo.txt
d:\users\path\program\otherstorage\06-12-2016\userinfo.txt
d:\users\path\program\storage\data\userinfo.txt
d:\users\path\program\otherstorage\data\userinfo.txt
Note: storage, otherstorage, storageother, storage2, storagegh are all arbitrary names as these folders are named accoring to end-user wishes.
I would want to export two separate variables for
d:\users\path\program\storage
and
d:\users\path\program\otherstorage
I would also need to do this for \data\userinfo.txt
So if searching for \data\userinfo.txt it would return
d:\users\path\program\storage\data\userinfo.txt
d:\users\path\program\otherstorage\data\userinfo.txt
I would also want to isolate both
d:\users\path\program\storage
and
d:\users\path\program\otherstorage
and use it as (separate) local variables.
I would need to note that installing/downloading any external scripting tools/aids would not be a suitable solution as I work on a lot of computers, most of which I do not have internet access and/or sufficient permissions for external downloads/installations so anything that is not integrated into the bat and needs to be imported separately is a bad idea.
Also, I am working on Windows XP SP3 but I would need this bat to be able to run on XP SP2, XP SP3, Windows 7, Windows 10, Windows NT, Windows 2000.
Any help would be appreciated.
Please note that
d:\users\path\program
would also be an acceptable variable. In this case I would manually amend the remainder of the path or would rely on end-user (my coworkers) input to complete the path correctly. The last has proven to be a fools errand.
The way that I've been handling it until now is to look for a .exe that I KNOW will be in both folders. This is a part of my code below edited to match the current example.
#echo off
SETLOCAL
echo Program will now look for program.exe and programgh.exe. Please input, when asked, matching part of the path for these files.
echo Example:
echo d:\users\path\program\storage\bin\program.exe
echo d:\users\path\program\otherstorage\bin\programgh.exe
echo In above example matching part is d:\users\path\program so you would enter that when prompted
echo Please do not input the last pathing mark: \ (backslash)
echo -------------searching---------------
::I am exporting errors to nul as I don't want them to be spammed by errors and other data that they would think is their fault
where /r c: program*.exe 2>nul
where /r d: program*.exe 2>nul
where /r e: program*.exe 2>nul
where /r f: program*.exe 2>nul
set /p dualpath="Please enter matching paths for program folder: "
After that I would proceed to work with %dualpath% variable.
As it usually happens (to me at least) most people would just copy the example path without taking a look at what the program has spat out and would be confused as to why the program did not work. Either that or would copy everything up to program.exe and programgh.exe - including the otherstorage\bin\ without noticing that \storage\ and \otherstorage\ do not match.
I think this now covers all the comments or additional questions and clarifies a bit better what I need. Thank you all for help so far and I hope that this is easier to understand.
If a Windows cmd command allows wildcards in a (partially or fully qualified) path then wildcards must be used only in the path leaf (i.e. the last item or container in the path). However, you could apply findstr regex to narrow command output e.g. as follows:
where /r d:\ userinfo.txt | findstr /I "\\storage2*\\data\\userinfo.txt"
above command wold narrow output to paths ending with \storage\data\userinfo.txt and \storage2\data\userinfo.txt
Another example - narrow output to paths ending with \storageX\data\userinfo.txt where X is either nothing or any decimal cipher [0-9]:
dir /B /S d:\userinfo.txt | findstr /I "\\storage[0-9]*\\data\\userinfo.txt"
Put the paths to environment variables (with _var prefix for easier next identification), e.g. _varstorage, _varstorage2, …
#ECHO OFF
SETLOCAL EnableExtensions
for /F "delims=" %%F in ('
dir /B /S "d:\userinfo.txt" ^| findstr /I "\\storage[0-9]*\\data\\userinfo.txt"') do (
for /D %%D in ("%%~dpF..") do (
set "_var%%~nxD=%%~fD"
rem %%~fD path
rem %%~nxD last item in above path
rem _var variable name prefix
)
)
rem show result:
set _var
See also next %%~nxD and %%~D explanation: Command Line arguments (Parameters): Parameter Extensions
If I got your intention right, the following script should do what you want:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=D:\" & rem "D:\", "D:\users",..., or "D:\users\path\program"
set "_FILE=userinfo.txt"
rem // Initialise index:
set /A "INDEX=1"
rem // Search for the specified file in the given root directory:
for /F "delims=" %%F in ('dir /B /S "%_ROOT%\%_FILE%"') do (
rem // Iterate once over the grandparent directory itself:
for /D %%D in ("%%F\..\..") do (
rem // Resolve the path of the grantparent directory;
set "ITEM=%%~fD"
rem // Initialise flag (non-empty means not yet stored):
set "FLAG=#"
rem // Toggle delayed expansion to avoid trouble with exclamation marks:
setlocal EnableDelayedExpansion
rem // Iterate over all currently stored grantparent paths:
for /F "tokens=1,* delims==" %%V in ('2^> nul set $ARRAY[') do (
rem // Clear flag in case current grandparent has already been stored:
if /I "!%%V!"=="!ITEM!" set "FLAG="
)
rem // Check flag:
if defined FLAG (
rem // Flag is empty, so current grandparent needs to be stored:
set "$ARRAY[!INDEX!]=!ITEM!"
rem // Transfer stored grandparent over localisation barrier:
for /F "delims=" %%E in ("$ARRAY[!INDEX!]=!ITEM!") do (
endlocal
set "%%E"
)
rem // Increment index
set /A "INDEX+=1"
) else endlocal
)
)
rem // Retrieving final count of grandparent directories:
set /A "INDEX-=1"
rem // Return stored grandparent paths:
set $ARRAY[
endlocal
exit /B
This should return D:\users\path\programs\otherstorage and D:\users\path\programs\storage in your situation, which are stored in the variables $ARRAY[1] and $ARRAY[2], respectively. Due to the array-style variables, this approach is flexible enough to cover also cases where more than two grandparent directories are present.
Based on your above sample this batch
#Echo off
Set Search=\\data\\userinfo.txt
pushd "D:\Users\path\program
For /f "Delims=" %%A in (
'Dir /B/S/A-D userinfo.txt ^|findstr "%Search%$"'
) Do Call :Sub "%%~fA" "%%~dpA.."
Popd
Goto :Eof
:Sub FullName DrivePath
Echo Found %~nx1
Echo in %~dp1
Echo Granny %~nx2
Set "Granny=%~nx2"
Echo in %~dp2
Echo -------
Should give this output (only partially tested)
Found userinfo.txt
in D:\Users\path\program\storage\data\
Granny storage
in D:\Users\path\program\
-------
Found userinfo.txt
in D:\Users\path\program\storage2\data\
Granny storage2
in D:\Users\path\program\
-------
The backslash in Search has to be doubled as it is an escape char for findstr

Loop through files in a folder and check if they have different extensions

I have a folder that contains files; each document should have .pdf and .xml format. I need to write a BAT file to run from a scheduled task to verify that both documents exist for each.
My logic is:
loop through files in the folder
strip each file to its name without extension
check that same name files exist for both .xml and pdf.
if not mark a flag variable as problem
when done, if the flag variable is marked, send an Email notification
I know how to use blat to sending email, but I'm having trouble to execute the loop. I found a way to get path and file name without extension but can't merge them.
I've used batch files a few time, before but I'm far from an expert. What am I missing?
Here's the code I have so far:
set "FolderPath=E:\TestBat\Test\"
echo %FolderPath%
for %%f in (%FolderPath%*) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set Name=%%~nxA
)
echo Folder is: %Folder%
echo Name is: %Name%
if NOT EXIST %FolderPath%%name%.xml
set flag=MISSING
if NOT EXIST %FolderPath%%name%.pdf
set flag=MISSING
)
echo %Flag%
pause
There is no need for fancy code for a task such as this:
#Echo Off
Set "FolderPath=E:\TestBat\Test"
If /I Not "%CD%"=="%FolderPath%" PushD "%FolderPath%" 2>Nul||Exit/B
Set "flag="
For %%A In (*.pdf *.xml) Do (
If /I "%%~xA"==".pdf" (If Not Exist "%%~nA.xml" Set "flag=MISSING")
If /I "%%~xA"==".xml" (If Not Exist "%%~nA.pdf" Set "flag=MISSING")
)
If Defined flag Echo=%flag%
Timeout -1
Something like this :
set "FolderPath=E:\TestBat\Test\"
pushd "%FolderPath%"
for %%a in (*.xml) do (
if exist "%%~na.pdf"(
echo ok
) else (
rem do what you want here
echo Missing
)
)
popd
Is this what you want?
#echo off
setlocal enabledelayedexpansion
set "FolderPath=E:\TestBat\Test\"
echo !FolderPath!
for /f "usebackq delims=" %%f in (`dir !FolderPath! /B`) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set name=%%~nxA
)
echo Folder is: !Folder!
echo Name is: !name!
if NOT EXIST !FolderPath!!name!.xml set flag=MISSING
if NOT EXIST !FolderPath!!name!.pdf set flag=MISSING
)
echo Flag: !flag!
pause
endlocal
You should reformat your code and keep in mind that the grama for batch file is critical. BTW, if you are trying to update the existing batch variable and read it later, you should enable localdelayedexpansion and use ! instead of %.
Keep it simple:
#echo off
pushd "E:\TestBat\Test" || exit /B 1
for %%F in ("*.pdf") do if not exist "%%~nF.xml" echo %%~nxF
for %%F in ("*.xml") do if not exist "%%~nF.pdf" echo %%~nxF
popd
This returns all files that appear orphaned, that is, where the file with the same name but the other extension (.pdf, .xml) is missing. To implement a variable FLAG to indicate there are missing files, simply append & set "FLAG=missing" to each for line and ensure FLAG is empty initially. Then you can check it later by simply using if defined FLAG.
Note: This does not cover the e-mail notification issue. Since I do not know the BLAT tool you mentioned, I have no clue how you want to transfer the listed files to it (command line arguments, temporary file, or STDIN stream?).
In case there is a huge number of files in the target directory, another approach might be better in terms of performance, provided that the number of file system accesses is reduced drastically (note that the above script accesses the file system within the for loop body by if exist, hence for every iterated file individually). So here is an attempt relying on a temporary file and the findstr command:
#echo off
pushd "E:\TestBat\Test" || exit /B 1
rem // Return all orphaned `.pdf` files:
call :SUB "*.pdf" "*.xml"
rem // Return all orphaned `.xml` files:
call :SUB "*.xml" "*.pdf"
popd
exit /B
:SUB val_pattern_orphaned val_pattern_missing
set "LIST=%TEMP%\%~n0_%RANDOM%.tmp"
> "%LIST%" (
rem // Retrieve list of files with one extension:
for %%F in ("%~2") do (
rem /* Replace the extension by the other one,
rem then write the list to a temporary file;
rem this constitutes a list of expected files: */
echo(%%~nF%~x1
)
)
rem /* Search actual list of files with the other extension
rem for occurrences of the list of expected files and
rem return each item that does not match: */
dir /B /A:-D "%~1" | findstr /L /I /X /V /G:"%LIST%"
rem // Clean up the temporary file:
del "%LIST%"
exit /B
To understand how it works, let us concentrate on the first sub-routine call call :SUB "*.pdf" "*.xml" using an example; let us assume the target directory contains the following files:
AlOnE.xml
ExtrA.pdf
sAmplE.pdf
sAmplE.xml
So in the for loop a list of .xml files is gathered:
AlOnE.xml
sAmplE.xml
This is written to a temporary file but with the extensions .xml replaced by .pdf:
AlOnE.pdf
sAmplE.pdf
The next step is to generate a list of actually existing .pdf files:
ExtrA.pdf
sAmplE.pdf
This is piped into a findstr command line, that searches this list for search strings that are gathered from the temporary file, returning non-matching lines only. In other words, findstr returns only those lines of the input list that do not occur in the temporary file:
ExtrA.pdf
To finally get also orphaned .xml files, the second sub-routine call is needed.
Since this script uses a temporary file containing a file list which is processed once by findstr to find any orphaned files per extension, the overall number of file system access operations is lower. The weakest part however is the for loop (containing string concatenation operations).

Wildcards for directory in Windows batch command

I need to copy the contents of a folder to another folder using a batch file - the problem I'm facing is that one of the parent folders will change every day, being named after today's date. So, for example, I have the following command:
xcopy /Y /S "\\auto-jenkins\Builds\2017\R1\\[0822]\EN\\*.*" "C:\Users\Administrator\Desktop\EN"
This works fine today, unfortunately tomorrow the [0822] will not exist and the files I need will be under [0823]. Does anyone know of a way I can use a wildcard in place of [0822]?
The [08**] folder will be the only folder below \R1 if that helps...
Does anyone know of a way I can use a wildcard in place of [0822]?
You don't need a wildcard. Use the current date (in the correct format) instead. Use the following batch file.
CopyFiles.cmd:
#echo off
setlocal
rem get the date
rem use findstr to strip blank lines from wmic output
for /f "usebackq skip=1 tokens=1,2" %%g in (`wmic Path Win32_LocalTime Get Day^,Month ^| findstr /r /v "^$"`) do (
set _day=00%%g
set _month=00%%h
)
rem pad day and month with leading zeros
set _month=%_month:~-2%
set _day=%_day:~-2%
xcopy /Y /S "\auto-jenkins\Builds\2017\R1[%_month%%_day%]\EN*.*" "C:\Users\Administrator\Desktop\EN"
endlocal
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
for /f - Loop command against the results of another command.
wmic - Windows Management Instrumentation Command.
Since there is only a single folder in the R1 directory anyway, you can use for /D to get its name:
for /D %%D in ("\\auto-jenkins\Builds\2017\R1\*") do (
xcopy /Y /S "%%~D\EN\*.*" "C:\Users\Administrator\Desktop\EN"
)
The * is a global wild-card that stands for any number of arbitrary characters. Instead of it, you could also use [????] so your folder name must consist of exactly four characters in between [].
You can use the automatic date variable %date which is country specific:
xcopy /Y /S "\auto-jenkins\Builds\2017\R1\[%date:~3,2%%date:~0,2%]\EN\*.*" "C:\Users\Administrator\Desktop\EN"
Here, the month and the day are extracted from the date string. First number is the start position (starting at 0), next number is the length.

comparing file size and modified date

I am trying to build a batch script to confirm both file size and modified date. as of i have been using different commands (diff, comp, and others) that are not giving me the needed outcome. both files are found remotely and are in different time zones so using a dir command output didnt work for me.
ask for computer name or keywork to pull list from a txt file
set /P "ComputerName=Please enter the computer name or the word batch to pull from computernames.txt: "
compare two locations
file1= (fixed server location)\file.zip(or txt)
file2= \\%ComputerName%\m$\file.zip(or txt)
compare date modified (this file is modified once a week but can not use time stamp since the file goes out to computers in different time zones and if the copy has an issue it reverts back to last successful file date or "beginning of time" time stamp)
compare size (files that fail a copy with default to a 0 size or size where it got stuck)
if file1 = file2
end or proceed to next file in batch
if file1 does not equal file 2 (both conditions)
export %ComputerName% name to file
once confirmed end or continue next in txt list
Not really sure this will work in your environment, but... while FAT partitions use the local time to save file timestamps, NTFS use UTC time. And this timestamp can be retrieved using robocopy
#echo off
setlocal enableextensions disabledelayedexpansion
call :getFileData "%cd%\file1.zip" file1
call :getFileData "%cd%\file2.zip" file2
echo file1 : %file1%
echo file2 : %file2%
if "%file1%"=="%file2%" (
echo Both files has the same size/timestamp
) else (
echo Files has different size/timestamp
)
goto :eof
:getFileData file returnVar
rem Prepare environment
setlocal enableextensions disabledelayedexpansion
set "fileData="
rem Retrieve file size and time stamp
for /f "tokens=1-3" %%a in ('
robocopy "%~dp1\." "%~dp1\." "%~nx1" /l /is /ts /nc /ndl /njh /njs 2^>nul
') do set "fileData=%%a %%b %%c"
rem Handle non existing files
if not defined fileData set "fileData=FileNotFound %random%%random%%random%"
rem Return or show data
endlocal & if "%~2"=="" (echo(%fileData%) else (set "%~2=%fileData%")
exit /b

Windows Shell Command to Show File Name and Last Access Time

I am trying to write a Windows command to list files and their last access times, sorted by access time.
I have used
dir [directory] /O:D /T:A /S /B > output.txt
This outputs the files in directory and sub directories in order by their last access time; however I also need it to output the last access time as well. How is this accomplished?
from within a batch file:
>output.txt (
for /f "delims=" %%F in ('dir /o:d /t:a /s /b "c:\myPath\*"') #echo %%~tF %%F
)
However, there are some things you need to be aware of:
The files are sorted by access timestamp within a directory. It does not sort by access timestamp across all the directories. Your original code has the same problem. To sort accross directories requires parsing the access timestamp and converting it into a string that will sort chronologically when ordered via SORT. Something like "yyyy-mm-dd hh24:mm". Even that is not particularly good because you don't have access to the seconds. You could use WMIC DATAFILE to list file names with last access timestamps at a sub-second level. But why bother, considering that...
The last access timestamp maintained by Windows is not reliable! There are many situations whereby an application can read a file and yet the last access timestamp is not updated. I've seen some reference material somewhere that talks about that, but I don't remember where.
If you still think you want to get a list of files sorted by last access timestamp for an entire folder hierarchy, then the following will work. Assume you want to list all files under "c:\test\"
wmic datafile where "drive='c:' and path like '\\test\\%'" get name, lastaccessed | sort
The timestamp will have the format YYYYMMDDhhmmssddddddZZZZ where
YYYY = year
MM = month
DD = day
hh = hour (24 hour format)
mm = minutes
ss = seconds
dddddd = micro seconds
ZZZZ = timezone, expressed as minutes difference from GMT (the 1st character is the sign)
EDIT
The wildcard search in WMIC causes terrible performance. Here is a version that iterates through all the folders in the root hierarchy, running WMIC against each specific folder (no wildcard). It has decent performance.
#echo off
setlocal disableDelayedExpansion
set "root=c:\test"
set "output=output.txt"
set "tempFile=%temp%\dir_ts_%random%.txt"
(
for /d /r "%root%" %%F in (.) do (
set "folder=%%~pnxF\"
set "drive=%%~dF"
setlocal enableDelayedExpansion
2>nul wmic datafile where "drive='!drive!' and path='!folder:\=\\!'" get name, lastaccessed|findstr /brc:[0-9]
endlocal
)
) >"%tempFile%
sort "%tempFile%" >"%output%"
del "%tempFile%"

Resources