looping the CACLS function in batch - loops

I would like to lock a series of file from my staff so they can not delete them i have thus compiled a script wich puts the CACLS function into a loop. however this is not taking effect.
could somebody please explain why?
FOR /F %%i IN (c:\file.txt) DO CACLS %%i /p :n /y
I have been able to narrow it down to the /y at the end how can i continue to Automate the yes?

There are a couple of things wrong.
Firstly you haven't specified a user/group that you want to apply the permissions to
Example
CACLS %%i /p Everyone:n /y
Secondly, there is no /y switch for cacls. If you want to automatically say y to the confirmation you can use this
echo y| CACLS %%i /p Everyone:n /y
So your full batch file would look similar to this
FOR /F %%i IN (c:\file.txt) DO echo y| CACLS %%i /p Everyone:n
Hope this helps

Related

Robocopy script to transfer user data from old PC to new PC

I am trying to write a script that I can use to remotely transfer data from an end user's computer, to a new one I am preparing for them. I will need to transfer data from multiple user profiles, so I have written it to cycle through the user profiles on the old machine, but I am unsure of the correct syntax in a couple places, specifically what variable I need to reference the current user folder as the script cycles through them (see the question marks in the directories listed below).
I wrote it to only copy user profiles that have been used in the last 90 days. I would like to copy a few profiles such as Public, Default, etc regardless of age, but I will probably just add a few more Robocopy lines to accomplish that.
Can anyone advise me on what the syntax needs to be where the question marks appear below? This would be $_ in Powershell, but I'm not sure what it is in a CMD batch file.
Thanks in advance,
Andrew
#echo off
Set /p OldPC=Please enter the old PC name:
Set /p NewPC=Please enter the new PC name:
for /D %%D in ("\\%OldPC%\USERS\*") do (robocopy "\\%OldPC%\USERS\?\Desktop" "\\%NewPC%\Users\?\Desktop" /E /Z /W:10 /COPYALL /MAXAGE:90
for /D %%D in ("\\%OldPC%\USERS\*") do (robocopy "\\%OldPC%\USERS\?\Documents" "\\%NewPC%\Users\?\Documents" /E /Z /W:10 /COPYALL /MAXAGE:90
for /D %%D in ("\\%OldPC%\USERS\*") do (robocopy "\\%OldPC%\USERS\?\Favorites" "\\%NewPC%\Users\?\Favorites" /E /Z /W:10 /COPYALL /MAXAGE:90
for /D %%D in ("\\%OldPC%\USERS\*") do (robocopy "\\%OldPC%\USERS\?\Pictures" "\\%NewPC%\Users\?\Pictures" /E /Z /W:10 /COPYALL /MAXAGE:90
I guess you needed more than what you asked.
From what I understood, you want to copy user profile folders for the users who have been using the computer since some date.
To solve the problem, it would be better to find users who logged on rather than finding any file that is edited. Finding edited files will consume too much time to just find the names of used user accounts.
Since there is wevtutil command that is used to deal with logged events, the code became quite simpler.
So the code looks like this:
#echo off
pushd %~dp0
setlocal EnableDelayedExpansion
::User Input
set /p OldPC=Please enter the old PC name:
set /p NewPC=Please enter the new PC name:
set /p UserName=Please enter the User name to use in %OldPC%:
set /p Password=Please enter the password to use in %OldPC%:
set /p MaxDate=Please enter the Maximum logon date:
cls
echo Deriving User Names that are used since %MaxDate%...
echo If this step takes too long, check if you typed correct user name and password.
wevtutil qe Security /r:%OldPC% /u:%UserName% /p:%Password% /f:text /q:"*[System[TimeCreated[#SystemTime>='%MaxDate%T00:00:00'] and (EventID=4624)]]" |^
findstr /b /c:" Account Name" >PossibleUserName.tmp1
dir /b "\\%OldPC%\Users" >UserProfileList.tmp1
findstr /g:"UserProfileList.tmp1" "PossibleUserName.tmp1"|sort >UserList.tmp2
del /q *.tmp1
cls
echo Formatting User List...
for /f "tokens=2 delims=: " %%a in (UserList.tmp2) do (
if not "!ln!"=="%%a" (
set "ln=%%a"
echo %%a>>FinalList.tmp
)
)
del /q *.tmp2
cls
echo Copying Files...
for /f "tokens=*" %%a in (FinalList.tmp) do (
echo robocopy "\\%OldPC%\Users\%%a\Desktop" "\\%NewPC%\Users\%%a\Desktop" /e /z /w:10 /copyall
echo robocopy "\\%OldPC%\Users\%%a\Documents" "\\%NewPC%\Users\%%a\Documents" /e /z /w:10 /copyall
echo robocopy "\\%OldPC%\Users\%%a\Favorites" "\\%NewPC%\Users\%%a\Favorites" /e /z /w:10 /copyall
echo robocopy "\\%OldPC%\Users\%%a\Pictures" "\\%NewPC%\Users\%%a\Pictures" /e /z /w:10 /copyall
)
echo Done!
del /q *.tmp
pause>nul
exit
Since you are trying to use the script from the remote computer, wevtutil command required log in information for your old PC.
Also, you need to input the date that you want to use in %MaxDate%, which will enable you to filter the logs since that date.
The date format should look like this: YYYY-MM-DD
For example, you should type 2017-01-01 if you want to filter users who used the computer since January 1, 2017.
If you set both old and new computers to share their Users Directories with correct properties, then you would be good to go with this code.
I hope this code would solve your problem.

Deleting and copying files using batch file

Im trying to copy files from one drive to another using a batch file, Which works! but we keep Changing file names on our main file which creates addition copys with diffrent names everytime its run. I dont want to delete the Copy file entirely bacause of the length of time the copy takes just to copy. I would like to Compare the 2 files and delete the files that are no longer on the main drive here is the test that im working on. Thanks for any help you can give me.
#echo
cls
If not exist "C:\Users\Jeremy\Desktop\Test Main\*.*" "Del "C:\Users\Jeremy\Desktop\Test Clone\*.*"
xcopy "C:\Users\Jeremy\Desktop\Test Main\*.*" "C:\Users\Jeremy\Desktop\Test Clone\*.*" /D /C /E /S /I /Y /V /H /R /F /d:01-01-1998
pause
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
you might want to look into robocopy, specifically with the /mir switch, which mirrors (copy all new files and delete all no longer existing files) the source folder to the target.
Thanks
This does work
#echo
cls
robocopy /MIR "C:\Users\Jeremy\Desktop\Test Main" "C:\Users\Jeremy\Desktop\Test Clone"
pause
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
But I would still like to understand if anyone can or wants to take the time to correct my original question
Try:
#echo off
cls
If not exist "C:\Users\Jeremy\Desktop\Test Main\*.*" "Del "C:\Users\Jeremy\Desktop\Test Clone\*.*"
xcopy "C:\Users\Jeremy\Desktop\Test Main\*.*" "C:\Users\Jeremy\Desktop\Test Clone\*.*" /D /C /E /S /I /Y /V /H /R /F /d:01-01-1998
If %errorlevel% EQU 2 (
echo You pressed CTRL+C to end the copy operation.
)
pause

Two For Loops Using %1 - Delayed Expansion?

My working batch file scans a long list of remote servers, copies anything there to a local server, checks the log file for a keyword, and if the keyword is found sends an email. I noticed it is always sending emails, even with a blank log file.
I discovered both FOR loops are using the %1 variable for their output - as seen in ECHO %1 and each line of the called :servermove. For lack of a better explanation it is not resetting %1 to null between loops.
I reviewed almost a dozen SO posts and am somewhat confident using SETLOCAL ENABLEDELAYEDEXPANSION would resolve this. That is where my understanding ends and I am unsuccessful thus far.
Here is the relevant code:
SET DATE=%date:~4,2%-%date:~7,2%-%date:~10,4%
SET HH=%time:~0,2%
SET MN=%time:~3,2%
SET TSTAMP=Time Run is %HH%%MN%
SET DATETIME=%DATE% at %HH%%MN%
SET LOGFILE="\\nt980a3\CreditFileImagesTransmission\LogFiles\%DATETIME%-File Move Log.txt"
SET MailDst=
SET MailSrc=
SET MailSrcName=Center to LDSD File Mover
SET OKMailSub=A Branch Has Sent You Some Files
ECHO %DATETIME% > %LOGFILE%
ECHO. >> %LOGFILE%
FOR /F "tokens=1" %%A IN (%~dp0SourceServers.txt) DO CALL :ServerMove %%A
:cleanuplogs
PUSHD "\\nt980a3\CreditFileImagesTransmission\LogFiles" &&(
FORFILES /S /M *.txt /D -45 /C "CMD /C DEL /Q #path"
) & POPD
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
:successmail
IF EXIST %temp%\to.txt DEL %temp%\to.txt
FOR %%a IN (%MailDst%) DO ECHO %%a>>%temp%\to.txt
"%~dp0sendmail.exe" /TO=%temp%\to.txt /FROM=%MailSrcName% ^<%MailSrc%^> /REF=%OKMailSub% /MESSAGE=%LOGFILE% /HOST=
:exit
EXIT
:ServerMove
DIR /S /B \\%1\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%1\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%1\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%1\CreditFileImagesTransmission\*.*"
I tried changing :mailtest to use %%B in both instances but that also fails. Placing SETLOCAL ENABLEDELAYEDEXPANSION and its counterpart ENDLOCAL before one or the other loop and changing the %%A to !A! does not work either.
Would someone kindly point out the error in my ways and offer suggestions or resources that will help me resolve this?
%1 is the first parameter provided to the procedure - either from the command-line (in the main procedure) or the parameter following the procedure name in call :procedurename parameter1.
In your case, %1 to :servermove is an entry from SourceServers.txt and %1 to :searchlog is each line from %LOGFILE%.
Since you've censored your batch, what you've posted makes little sense. For instance, the :searchlogs routine will take the first line from %LOGFILE% and go to successmail or cleanlogs depending on whether that first line contains the target string \\nt. What it does from there, we can't tell.
We're faced with an XY problem - trying to fix a solution, not a problem.
First problem: Don't use date as a user-variable. It's a "magic variable" which contains the date but it's overridden by a specific set statement.
Having run :servermove for each entry in SourceServers.txt, you are
- accumulating a directory list from \CreditFileImagesTransmission\*.* on that server.
- copying those files to server nt980a3 with a date/timestamp but not including the source-servername so any duplicate name anywhere will overwrite an earlier version. I suggest you include %1 into your destination-name.
- deleting subdirectories
- deleting files.
I'd suggest you simply remove the directory \\%1\CreditFileImagesTransmission\, then re-create it.
I'd also suggest that you add an extra line
goto :eof
after the del /q /s... line. This will cause execution to be transferred to the end-of-file (the colon in :eof is required) and may seem superfluous, but it ensures that the routine has a defined endpoint - if you add a further routine, there is no way the :servermove routine will continue into your new code.
After each server has been processed, you proceed to the :cleanuplogs routine, which I presume deletes logs older than 45 days.
Your next statement is a real problem. What it will do is grab the very first line of the logfile (which contains "%DATE% at %HH%%MN%" with the date resolved as you've set at the start and it then processes this line in :searchlog; there is no \\nt in this line, so errorlevel is set to 1, and the batch proceeds to :EXIT (not a good label in my view, since it's a keyword); executes an exitand should terminate the batch.
This appears not to be what it is actually doing, and I'm at a loss to explain why.
I'd suggest changing
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
to
:mailtest
find "\\nt" %LOGFILE%>NUL
IF NOT ERRORLEVEL 1 GOTO successmail
:failmail
echo "\\nt" was found in the log
pause
GOTO exit
but I can't test that...
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
You are missing a GOTO :EOF or similar goto here because it will drop through to the routine below once the above is finished.
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
I feel you can not carry the %1 of first for loop to others. Try to transfer that to another variable like below.
:ServerMove
set servername=%1
DIR /S /B \\%servername%\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%servername%\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%servername%\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%servername%\CreditFileImagesTransmission\*.*"
Cheers, G

Delete all files of specific type (extension) recursively down a directory using a batch file

I need to delete all .jpg and .txt files (for example) in dir1 and dir2.
What I tried was:
#echo off
FOR %%p IN (C:\testFolder D:\testFolder) DO FOR %%t IN (*.jpg *.txt) DO del /s %%p\%%t
In some directories it worked; in others it didn't.
For example, this didn't do anything:
#echo off
FOR %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
What I'm I missing in the second snippet? Why didn't it work?
You can use wildcards with the del command, and /S to do it recursively.
del /S *.jpg
Addendum
#BmyGuest asked why a downvoted answer (del /s c:\*.blaawbg) was any different than my answer.
There's a huge difference between running del /S *.jpg and del /S C:\*.jpg. The first command is executed from the current location, whereas the second is executed on the whole drive.
In the scenario where you delete jpg files using the second command, some applications might stop working, and you'll end up losing all your family pictures. This is utterly annoying, but your computer will still be able to run.
However, if you are working on some project, and want to delete all your dll files in myProject\dll, and run the following batch file:
#echo off
REM This short script will only remove dlls from my project... or will it?
cd \myProject\dll
del /S /Q C:\*.dll
Then you end up removing all dll files form your C:\ drive. All of your applications stop working, your computer becomes useless, and at the next reboot you are teleported in the fourth dimension where you will be stuck for eternity.
The lesson here is not to run such command directly at the root of a drive (or in any other location that might be dangerous, such as %windir%) if you can avoid it. Always run them as locally as possible.
Addendum 2
The wildcard method will try to match all file names, in their 8.3 format, and their "long name" format. For example, *.dll will match project.dll and project.dllold, which can be surprising. See this answer on SU for more detailed information.
You can use this to delete ALL Files Inside a Folder and Subfolders:
DEL "C:\Folder\*.*" /S /Q
Or use this to Delete Certain File Types Only:
DEL "C:\Folder\*.mp4" /S /Q
DEL "C:\Folder\*.dat" /S /Q
I wrote a batch script a while ago that allows you to pick a file extension to delete. The script will look in the folder it is in and all subfolders for any file with that extension and delete it.
#ECHO OFF
CLS
SET found=0
ECHO Enter the file extension you want to delete...
SET /p ext="> "
IF EXIST *.%ext% ( rem Check if there are any in the current folder :)
DEL *.%ext%
SET found=1
)
FOR /D /R %%G IN ("*") DO ( rem Iterate through all subfolders
IF EXIST %%G CD %%G
IF EXIST *.%ext% (
DEL *.%ext%
SET found=1
)
)
IF %found%==1 (
ECHO.
ECHO Deleted all .%ext% files.
ECHO.
) ELSE (
ECHO.
ECHO There were no .%ext% files.
ECHO Nothing has been deleted.
ECHO.
)
PAUSE
EXIT
Hope this comes in useful to anyone who wants it :)
I don't have enough reputation to add comment, so I posted this as an answer.
But for original issue with this command:
#echo off
FOR %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
The first For is lacking recursive syntax, it should be:
#echo off
FOR /R %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
You can just do:
FOR %%p IN (C:\Users\0300092544\Downloads\Ces_Sce_600) DO #ECHO %%p
to show the actual output.
this is it:
#echo off
:: del_ext
call :del_ext "*.txt"
call :del_ext "*.png"
call :del_ext "*.jpg"
:: funcion del_ext
#echo off
pause
goto:eof
:del_ext
set del_ext=%1
del /f /q "folder_path\%del_ext%"
goto:eof
pd: replace folder_path with your folder
Step 1:
Navigate to the folder in question using the cd command
For example:
cd C:\Users\tremanleo\Desktop\HoldLEOCMS
Step 2
Delete the the file type.
For Example:
DEL *.bak
If you are trying to delete certain .extensions in the C: drive use this cmd:
del /s c:\*.blaawbg
I had a customer that got a encryption virus and i needed to find all junk files and delete them.

How to rename a folder with a number (ie Folder1, Folder2, etc....)

I'm messing around with dos and batch files for the first time and I am trying to make a "program" to backup my Minecraft saves (lol). I want the program to rename the current save (in my MinecraftSaves folder) as "Backup#" before the next one is copied into the MinecraftSaves folder. Its simple enough to rename it, but I want it to save multiple folders, each incrementing a number at the end of the folder name (ie Backup1, Backup2, Backup3). Any help? I've looked all over but I couldn't find something exactly to fit my needs.
#Echo off
title Minecraft Backup
echo.
echo.
echo.
echo Do you want to backup you're Single Player World?
echo.
SET /P ANSWER=Do you want to continue (Y/N)?
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)
if /i {%ANSWER%}=={n} (goto :no)
if /i {%ANSWER%}=={no} (goto :no)
:no
PING 1.1.1.1 -n 1 -w 1000 >NUL
exit
:yes
ren C:\Users\Josh\Desktop\MinecraftSaves\SinglePlayer Backup
xcopy C:\Users\Josh\AppData\Roaming\.minecraft\saves C:\Users\Josh\Desktop\MinecraftSaves /-y /e /h
Thats what I have so far. I want to change the following to rename the SinglePlayer folder as backup1, and the next time I run it have it rename the new SinglePlayer folder as backup2. I'm trying to explain this as best I can. Maybe theres a simpler way to do this. I just need it to make backups with numbers on the backup folders. Hope thats clear enough.
Excuse me. I think I did not really understood your question. However, the following Batch file take an existent folder named CurrentSave and rename it to Backup-# adding 1 to the last Backup-# existent folder. The dash in the folder name make things easier.
#echo off
for /D %%d in (Backup-*) do set lastfolder=%%d
for /F "tokens=2 delims=-" %%n in ("%lastfolder%") do set /A nextnumber=%%n+1
move CurrentSave Backup-%nextnumber%
If this is not what you want, give us more details so we may help you.
EDIT
OK. The code I posted above works right, just a couple details are needed. Below is the code you must insert from :yes label on:
:yes
set lastfolder=Backup-0
for /D %%d in (C:\Users\Josh\Desktop\MinecraftSaves\Backup-*) do set lastfolder=%%~Nd
for /F "tokens=2 delims=-" %%n in ("%lastfolder%") do set /A nextnumber=%%n+1
ren C:\Users\Josh\Desktop\MinecraftSaves\SinglePlayer Backup-%nextnumber%
xcopy C:\Users\Josh\AppData\Roaming\.minecraft\saves C:\Users\Josh\Desktop\MinecraftSaves /-y /e /h
May I suggest you another modification?
SET /P ANSWER=Do you want to continue (Y/N)?
for %%a in (y yes) do if /i "%ANSWER%"=="%%a" goto yes
:no
Please let me know if you solved your problem.

Resources