Batch: Copying from computer to network drive - windows

I've written a batch file that will do some tests then copy the results to a network drive. This use to work fine for me but over the last few days I have noticed it doesn't work for me and other people have said it has never worked for them.
This is the section that I am calling to copy to M: which all computers on our network can see. The section is being called and the archived results folder is being created but nothing is being sent to the destination drive.
Can anybody see what I've done wrong?
:CopyResults
SET CLASSPATH=%CLASSPATH_ORIGINAL%
For /f "tokens=1-4 delims=/ " %%a in ('date /t') do (set mydate=%%a-%%b-%%c)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
set source="target"
set Archive= "Archived Results\Test Results - %CLIENTCHOICE% %mydate% At %mytime% Using %BROWSEROPTION%"
set ScreenshotDestination= "Archived Results\Test Results - %CLIENTCHOICE% %mydate% At %mytime% Using %BROWSEROPTION%\Screenshots"
mkdir %Archive%
echo %Archive%
echo d | xcopy %source% %Archive% /k /e /d /y /h /i
rem copy screenshots
set screenshots="Screenshots"
echo d | xcopy %screenshots% %ScreenshotDestination% /k /e /d /y /h /i
%Archive%\site\index.html
rem copy accross to M:
set Destination= "M:\ProductTesting\AutomationResults\%CLIENTCHOICE%\%mydate% At %mytime% Using %BROWSEROPTION% Ran By %username%"
set ScreenshotDestination= "M:\ProductTesting\AutomationResults\%CLIENTCHOICE%\%mydate% At %mytime% Using %BROWSEROPTION%\Screenshots"
set source="target"
mkdir %Destination%
echo %Destination%
echo d | xcopy %source% %Destination% /k /e /d /y /h /i
rem copy screenshots
set screenshots="Screenshots"
echo d | xcopy %screenshots% %ScreenshotDestination% /k /e /d /y /h /i
GOTO Del

Related

Delete Folders on Remote PC with Certain names

This is a sample code that allows me to delete all folders with the name ".RemoveAsap" attached to them
#echo on
set dir="\\TestPC2\c$\Users"
FOR /D /R %dir% %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
pause
exit
Simply running the code as is runs perfectly but when I try to make the code more interactive, I get the error
#echo on
cd C:\Users\User1\Desktop\Test\
TYPE con >> LowDASD.txt
For /F %%A in (LowDASD.txt) do echo "\\%%A\c$\users\" >> LowDASD2.txt
set "LwDs"="LowDASD2.txt"
FOR /D /R "%LwDs%" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
pause
LowDASD2.txt would be the address/ directory location where the directories will be deleted, IE \\TestPC2\c$\Users
The code does not delete anything or give an error that "the path is too long" at least it was doing that with the previous variations that I was trying. If someone can help me with this, i would greatly appreciate it.
Try using FORFILES, instead of the command FOR, this way you can make it work like this:
:: forfiles /p "folder_location" 'args' '/c "cmd /c del /f /q #path"'
:: So...
cd C:\Users\User1\Desktop\Test\
TYPE con >> LowDASD.txt
For /F %%A in (LowDASD.txt) do echo "\\%%A\c$\users\" >> LowDASD2.txt
set "LwDs=LowDASD2.txt"
forfiles /p %LwDs% /s /c "cmd /c del /f /q #path"
:: You can use '/d -90' to delete files older than 90 days in the folder
FOR /D /R "%LwDs%" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
Simply will not work, as %LwDs% is a filename.
FOR /F "usebackq delims=" %%j in ("%LwDs%") do FOR /D /R "%%j" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
You would think might work - %%j being assigned to each entry in the %LwDs% file in turn; usebackq used because the filename is "quoted" (see for /? from the prompt for documentation)
But it doesn't - the for /d /r syntax doesn't accept metavariables...
So - try
FOR /F "usebackq delims=" %%j in ("%LwDs%") do set "target=%%j"&call :expunge
Where expunge is an internal subroutine. The colon is required
:expunge
echo target="%target%"
FOR /d /r "%target%" %%X IN (*.RemoveAsap) DO echo RMDIR /S /Q "%%X"
echo ====================
goto :eof
An internal subroutine should be placed after an unconditional goto, which should in your case follow the pause
pause
goto :eof
Where :eof (compulsory colon again) is defined as the physical end-of-file and should not be used as a user-label. Reaching physical end-of-file returns from a call.
Always verify against a test directory before applying to real data.
Note that the rmdir is merely being echoed for testing purposes - remove the echo keyword after testing to activate.
=== Extension
The full code should thus be
#echo on
set dir="\\TestPC2\c$\Users"
FOR /F "usebackq delims=" %%j in ("%LwDs%") do set "target=%%j"&call :expunge
pause
exit
:expunge
echo target="%target%"
FOR /d /r "%target%" %%X IN (*.RemoveAsap) DO echo RMDIR /S /Q "%%X"
echo ====================
goto :eof

How to delete subfolders and files from parent folders found in the variable of a bat script?

What I'm trying to do is find all the folders named "temp" on local disk C and then delete all files and subfolders that are inside it, but I don't know how to delete it, I only managed to get to the part of finding all folders and put them in the variable, but I don't know the correct code to delete. Help.
#echo off
setlocal
setlocal enabledelayedexpansion
#echo off
for /d /r "c:\" %%i in (temp) do (
#if exist "%%i" (
#set _variable=%%i
#echo !_variable!
)
)
endlocal
#echo off && setlocal enabledelayedexpansion
cd /d "C:\" && for /f tokens^=* %%i in ('dir /s /b /a:d "temp"')do (
echo\ Current Folder: "%%~i"
echo\ RmDir /q /s "%%~i"
echo\ MkDir "%%~i"
)
%__APPDIR__%\Timeout.exe /t -1 & endlocal & goto :EOF
1) Go to the drive:
cd /d "C:\"
2) Use For /f with dir /s /b /a:d instead For /D /R
for /f tokens^=* %%i in ('dir /s /b /a:d "temp"')do...
3) Don't need to delete the files in the target folder, just remove this folder and recreate it again...
RmDir /q /s "%%~i" && MkDir "%%~i\*"
Outputs look like this:
Current Folder: "C:\Program Files (x86)\Google\Temp"
rmdir /q /s "C:\Program Files (x86)\Google\Temp"
mkdir "C:\Program Files (x86)\Google\Temp\"
Current Folder: "C:\Program Files (x86)\Steam\steamapps\temp"
rmdir /q /s "C:\Program Files (x86)\Steam\steamapps\temp"
mkdir "C:\Program Files (x86)\Steam\steamapps\temp\"
Current Folder: "C:\ProgramData\Microsoft\Windows\WER\Temp"
rmdir /q /s "C:\ProgramData\Microsoft\Windows\WER\Temp"
mkdir "C:\ProgramData\Microsoft\Windows\WER\Temp\"
Current Folder: "C:\Users\All Users\Microsoft\Windows\WER\Temp"
rmdir /q /s "C:\Users\All Users\Microsoft\Windows\WER\Temp"
mkdir "C:\Users\All Users\Microsoft\Windows\WER\Temp\"
Current Folder: "C:\Users\Default\AppData\Local\Temp"
rmdir /q /s "C:\Users\Default\AppData\Local\Temp"
mkdir "C:\Users\Default\AppData\Local\Temp\"
Current Folder: "C:\Users\ecker\AppData\Local\Temp"
rmdir /q /s "C:\Users\ecker\AppData\Local\Temp"
mkdir "C:\Users\ecker\AppData\Local\Temp\"
Current Folder: "C:\Users\ecker\AppData\Local\Intel\CUIPromotions\Temp"
rmdir /q /s "C:\Users\ecker\AppData\Local\Intel\CUIPromotions\Temp"
mkdir "C:\Users\ecker\AppData\Local\Intel\CUIPromotions\Temp\"
Current Folder: "C:\Users\ecker\AppData\Local\Packages\windows_ie_ac_001\AC\Temp"
rmdir /q /s "C:\Users\ecker\AppData\Local\Packages\windows_ie_ac_001\AC\Temp"
mkdir "C:\Users\ecker\AppData\Local\Packages\windows_ie_ac_001\AC\Temp\"
Current Folder: "C:\Windows\Temp"
rmdir /q /s "C:\Windows\Temp"
mkdir "C:\Windows\Temp\"
Current Folder: "C:\Windows\assembly\temp"
rmdir /q /s "C:\Windows\assembly\temp"
mkdir "C:\Windows\assembly\temp\"
mkdir "C:\Windows\assembly\NativeImages_v4.0.30319_64\Temp\"
Current Folder: "C:\Windows\System32\DriverStore\Temp"
rmdir /q /s "C:\Windows\System32\DriverStore\Temp"
mkdir "C:\Windows\System32\DriverStore\Temp\"
Current Folder: "C:\Windows\WinSxS\Temp"
rmdir /q /s "C:\Windows\WinSxS\Temp"
mkdir "C:\Windows\WinSxS\Temp\"
Verify in your test the outputs and for effective execution, remove echo in:
#echo off && setlocal enabledelayedexpansion
cd /d "C:\" && for /f tokens^=* %%i in ('dir /s /b /a:d "temp"')do (
echo\ Current Folder: "%%~i"
echo\ RmDir /q /s "%%~i"
echo\ MkDir "%%~i"
)
%__APPDIR__%\Timeout.exe /t -1 & endlocal & goto :EOF
Or use this short option to suppress a possible error message for any folder in use or some other type of error
#echo off
setlocal enabledelayedexpansion && cd /d "C:\"
for /f "tokens=*" %%i in ('dir /s /b /a:d "temp"
')do 2>nul >nul (RmDir /q /s "%%~i" && MkDir "%%~i")
"%__APPDIR__%\Timout.exe" -1 & endlocal & goto :EOF
And, of course, a slightly smaller option...
#echo off
cd/d "C:\" & setlocal enabledelayedexpansion
for /f tokens^=* %%i in ('dir/s/b/a:d "temp"
')do 2>nul (RmDir /q /s "%%~i" && MD "%%~i")
"%__APPDIR__%\Timeout.exe" /t -1 && endlocal
For command line help, you can use /?:
RmDir /?, For /?, MkDir /?, Endlocal /?, SetLocal /?
On the internet, you can get more help on:
For /f
Endlocal
Goto :EOF
Timeout.exe
EnableDelayedExpansion
Conditional Execution || && ...

icacls broken in brackets

This is actually working but not in the format I prefer. The code below will achieve what I want. Makes a folder in any writable standard User Profile (I am aware it wont work in some system profiles like Default etc.) that some software needs and also gives it relevant permission.
for /d %%A in ("C:\Users\*") do mkdir "%%~fA\AppData\Local\Folder1"
for /d %%A in ("C:\Users\*") do mkdir "%%~fA\AppData\Local\Folder1_Ltd"
for /d %%A in ("C:\Users\*") do icacls "%%~fA\AppData\Local\Folder1" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
for /d %%A in ("C:\Users\*") do icacls "%%~fA\AppData\Local\Folder1_Ltd" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
This seems a bit over the top though. I am wanting to just have the one loop through the user folders and then use brackets to list the commands, saving a user loop for every function. However when I try the below, it doesn't even make the folders. If I debug using command line it stops at "everyone" was unexpected at this time. I'm not sure why? Any advice be welcome, thanks.
for /d %%A in ("C:\Users\*") do (
mkdir "%%~fA\AppData\Local\Folder1"
mkdir "%%~fA\AppData\Local\Folder1_Ltd"
icacls "%%~fA\AppData\Local\Folder1" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
icacls "%%~fA\AppData\Local\Folder1_Ltd" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
)
pause
You've to escape all the closing parentheses inside the (code block) to not being interpreted as the end of the block.
for /d %%A in ("C:\Users\*") do (
mkdir "%%~fA\AppData\Local\Folder1"
mkdir "%%~fA\AppData\Local\Folder1_Ltd"
icacls "%%~fA\AppData\Local\Folder1" /T /C /grant(:r^) "Everyone":(OI^)(CI^)(F^) /inheritance:e
icacls "%%~fA\AppData\Local\Folder1_Ltd" /T /C /grant(:r^) "Everyone":(OI^)(CI^)(F^) /inheritance:e
)
pause
Edit as eryksun suggested using a subroutine is an alternative (albeit using an editor to insert the ^ escapes is no big deal)
#Echo off
for /d %%A in ("C:\Users\*") do Call :Sub "%%~fA"
pause
Goto :Eof
:Sub
mkdir "%~f1\AppData\Local\Folder1"
mkdir "%~f1\AppData\Local\Folder1_Ltd"
icacls "%~f1\AppData\Local\Folder1" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
icacls "%~f1\AppData\Local\Folder1_Ltd" /T /C /grant(:r) "Everyone":(OI)(CI)(F) /inheritance:e
Another alternative could be to remove unneeded parenthesis and quote required ones
#echo off
setlocal enableextensions disabledelayedexpansion
for /d %%A in ("C:\Users\*") do (
for %%F in ("%%~fA\AppData\Local\Folder1" "%%~fA\AppData\Local\Folder1_Ltd") do (
mkdir "%%~fF"
icacls "%%~fF" /T /C /grant:r "Everyone":"(OI)(CI)(F)" /inheritance:e
)
)
If you want to keep the parenthesis in the grant switch, then you can
#echo off
setlocal enableextensions disabledelayedexpansion
for /d %%A in ("C:\Users\*") do (
for %%F in ("%%~fA\AppData\Local\Folder1" "%%~fA\AppData\Local\Folder1_Ltd") do (
mkdir "%%~fF"
icacls "%%~fF" /T /C "/grant(:r)" "Everyone":"(OI)(CI)(F)" /inheritance:e
)
)
note: Both cases tested on windows 10. I can not test at this moment if the icacls hability to deal with quoted arguments (in the /grant case) is present in previous OS versions.
note2: Tested without problems (well, /inheritance switch did not exist) with the Windows 2003 server SP2 version of the icacls.exe (the first version published). As pointed by eryksun, the additional quotes are removed by the CRT.
You could use WMI to access only normal users profiles too:
#Echo Off
For /F "Skip=1 Delims=" %%A In (
'"WMIc Path Win32_UserProfile Where (Special!='True') Get LocalPath"'
) Do For /F "Delims=" %%B In ("%%A") Do Call :Sub %%B
Pause>Nul
GoTo :EOF
:Sub
For %%A In (Folder1 Folder1_Ltd) Do (If Not Exist "%*\AppData\Local\%%A\" (
MD "%*\AppData\Local\%%A")
ICACLS "%*\AppData\Local\%%A" /T /C /Q /grant:r Everyone:(OI^)(CI^)F /inheritance:e)

batch delete old files and empty folders

I have a batch file that works on my local machine (Windows 7), but doesn't fully work on the server it is intended to live on(Windows 2008 R2 Service Pack 1).
It needs to delete files older than a specified number of days in all listed folders, then delete empty folders and sub-folders.
Script:
set DaysOld=3
set "folders[0]=C:\Test\BatchDel\1"
set "folders[1]=C:\Test\BatchDel\2"
set "folders[2]=C:\Test\BatchDel\3"
set "folders[3]=C:\Test\BatchDel\DNE"
for /F "tokens=1* delims==" %%s in ('set folders[') do (
forfiles /p "%%t" /s /m * /D -%DaysOld% /C "cmd /c del #path"
)
for /f "delims=" %%d in ('dir /ad/b/s ^| sort /R') do rd "%%d"
pause
When run on my local machine (spacing added):
C:\Test\BatchDel>set DaysOld=3
C:\Test\BatchDel>set "folders[0]=C:\Test\BatchDel\1"
C:\Test\BatchDel>set "folders[1]=C:\Test\BatchDel\2"
C:\Test\BatchDel>set "folders[2]=C:\Test\BatchDel\3"
C:\Test\BatchDel>set "folders[3]=C:\Test\BatchDel\DNE"
C:\Test\BatchDel>for /F "tokens=1* delims==" %s in ('set folders[') do (forfiles /p "%t" /s /m * /D -3 /C "cmd /c del #path" )
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\1" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\2" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\3" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\DNE" /s /m * /D -3 /C "cmd /c del #path" )
ERROR: The specified directory does not exist.
C:\Test\BatchDel>for /F "delims=" %d in ('dir /ad/b/s | sort /R') do rd "%d"
C:\Test\BatchDel>rd "C:\Test\BatchDel\3"
C:\Test\BatchDel>rd "C:\Test\BatchDel\2"
C:\Test\BatchDel>rd "C:\Test\BatchDel\1"
The directory is not empty.
C:\Test\BatchDel>pause
Press any key to continue . . .
When I run it on the server it asks for permission to delete each folder. (spacing added).
F:\data\Scripts>set DaysOld=5
F:\data\Scripts>set "folders[0]=F:\data\Environments\TestA\Cache_Data"
F:\data\Scripts>set "folders[1]=F:\data\Environments\TestB\Cache_Data"
F:\data\Scripts>for /F "tokens=1* delims==" %s in ('set folders[') do (forfiles /p "%t" /s /m * /D -5 /C "cmd /c del #path" )
F:\data\Scripts>(forfiles /p "F:\data\Environments\TestA\Cache_Data" /s /m * /D -5 /C "cmd /c del #path" )
F:\data\Environments\TestA\Cache_Data\0432f59d-9fd1-46ed-8579-9ebe358113fb\*, Are you sure (Y/N)?
I need it to delete the empty folders on the server without pressing Y for each one.
EDIT:
I updated the script. Thanks aschipfl! it is now closer to working. It is now asking Y/N to delete each folder.
EDIT 2: updated the outputs.
I found this solution:
for /F "tokens=1* delims==" %%s in ('set folders[') do (
forfiles /p "%%t" /s /m *.* /D -%DaysOld% /C "cmd /c del #path"
for /f "delims=" %%d in ('dir "%%t" /s /b /ad ^| sort /r') do rd "%%d"
)

Copy a txt file with today date as file name (YYMMDD)

Everyday I create a data log with today's date (eg. ERR150921.txt). I need to copy this file to the server like a backup.
This is my current code:
SET ServerPath=\\IYA-PC\Shared
SET ClientPath=%USERPROFILE%\Documents\Data Log
echo.
echo Copying Files to Server...
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\*.txt" /B /O:F') DO SET NewestFile=%%I
xcopy "%ClientPath%" "%ServerPath%\%NewestFile%" /s /c /d /e /h /i /r /y
I got it from a post here. It copies the recently updated files.
The problem is that I do not need all the updated files. I just need to copy the file created today.
This sample will copy every files that have today date as name before extension. ie it will copy any of this;
"ERR150921.txt"
"21184150921.txt"
"2526150921.txt"
"29056-150921.txt
"150921.txt"
"ABCDEF-150921.txt"
.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "_timestamp=%YY%%MM%%DD%"
SET "ServerPath=\\IYA-PC\Shared"
SET "ClientPath=%USERPROFILE%\Documents\Data Log"
echo.
echo Copying Files to Server...
setlocal enabledelayedexpansion
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\*.txt" /B') DO (
set "filename=%%~nI"
if "!filename:~-6!"=="%_timestamp%" (
echo xcopy "%%~I" "%ServerPath%\%%~nxI" /s /c /d /e /h /i /r /y
)
)
Get today's date, and transform it to your file name
SET ServerPath=\\IYA-PC\Shared
SET ClientPath=%USERPROFILE%\Documents\Data Log
echo.
echo Copying Files to Server...
SET FILE_NAME=ERR%date:~2,2%%date:~5,2%%date:~8,2%.txt
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\%FILE_NAME%" /B /O:F') DO SET NewestFile=%%I
xcopy "%ClientPath%" "%ServerPath%\%NewestFile%" /s /c /d /e /h /i /r /y

Resources