I need to backup an existing folder with date-time stamp and replace it (delete and recreate) with new content inside the folder.
Does anyone have a script to do th
The command date
with parameter /T
outputs the current date in format defined by configured country for current user account. Exactly the same date string can be accessed by referencing dynamic environment variable DATE
for example with %DATE%
.
The command time
with parameter /T
outputs the current time in format defined by configured country for current user account. Exactly the same time string can be accessed by referencing dynamic environment variable TIME
for example with %TIME%
.
What happens on execution of this command line?
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
for
respectively cmd.exe
processing the batch file starts in background one more command process using %ComSpec% /c
with the command line between '
. So executed in background is following with Windows installed in C:\Windows
:
C:\Windows\System32\cmd.exe /c date /t
The output of command date
to handle STDOUT of this command process in background is captured by FOR respectively Windows command processor instance executing the batch file.
The captured line is split up into three substrings using /
as string delimiter assigned to the loop variables a
, b
and c
which are concatenated together in reverse order with underscore as delimiter.
This task can be done much faster by replacing 'date /t'
by "%DATE%"
. In this case FOR processes the date string expanded by already running cmd.exe
on parsing this command line before executing FOR. So there is no starting of one more cmd.exe
in background and capturing its output just to process the same date string which makes batch file execution a bit faster.
The same is true for 'time /t'
which can be replaced by "%TIME%"
.
But the two FOR loops could be completely optimized away by using string substitution as described for example by answer on What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean? and region dependent date and time format is well known for example by running in a command prompt window:
echo %DATE% %TIME%
This command outputs on my computer with German date/time format according to configured country:
24.07.2019 20:15:29,90
It can be seen on this output that the original code would not work on my Windows computer with my account because of date string contains .
and not /
and time string contains a comma.
So better would be using a region independent solution as explained very detailed in answer on Why does %date% produce a different result in batch file executed as scheduled task? The disadvantage is that execution of wmic.exe
takes much longer than cmd.exe
needs to reformat date and time string to yyyy_MM_dd_HHmm
. However, the batch file is executed most likely not very often per day, and so it does not really matter if execution to get date/time in this format takes some milliseconds or about one second.
Copying the entire folder is not really necessary in this case. It should be enough to rename it with:
ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"
The command move
could be also used if command ren
cannot be used for unknown reasons.
However, the main problem is missing knowledge about how and when to use delayed expansion. Open a command prompt, run set /?
and read the output help explaining on an IF and a FOR example delayed environment variable expansion.
The issue here is that backup_folder
is not defined on executing the command lines referencing it with %backup_folder%
because of all occurrences of %variable%
are replaced by Windows command processor already on parsing entire command block starting here with (
on IF condition at top by current value of the referenced environment variable before executing the command IF.
So executed on existing release folder is:
set backup_folder=
MD \\servername\foldername\
REM Copy current folder to backup folder
Copy \\servername\foldername\Release \\servername\foldername\
REM Delete Existing Release folder
RD \\servername\foldername\Release /S /Q
This can be seen by debugging the batch file.
See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The solution is here avoiding the command block by changing the first IF condition.
Fast region dependent solution:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
ren "%ApplicationDeploymentFolderPath%\Release" "%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
Slower region independent solution:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "BackupDateTime=%%I"
set "BackupDateTime=%BackupDateTime:~0,4%_%BackupDateTime:~4,2%_%BackupDateTime:~6,2%_%BackupDateTime:~8,4%"
ren "%ApplicationDeploymentFolderPath%\Release" "%BackupDateTime%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
ren /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?