Unable to delete folders currently working on using batch file - batch-file

#echo off
rem setting folder variables
set "mymov=D:\Movies\My"
set "hermov=D:\Movies\Her"
set "themmov=D:\Movies\Them"
set folders=%mymov% %hermov% %themmov%
set ext=".mp4" ".mov" ".avi"
set test=0
for %%f in (%folders%) do (
echo "searching in %%f"
cd /D %%f
for %%i in (*.*) do (
for %%b in (%ext%) do (
if "%%~xi"==%%b (
set test=1
echo "match_found_not_deleting %%f")
)
)
if %test%==0 (
echo deleting %%f
rd /s /q %%f
)
)
I am trying to delete the folders stored in %%f but as my batch file is processing it I get an error that it is being used in some other process.
How can i fix it?
Please help.

Windows thinks that another application needs that folder and will not allow deletes until the other application is done using it. Try these items to find what else is accessing your folder.
check if you have another command window or windows explorer that is in (or under) that folder.
Check if you have a application open that is using a file in (or under) that folder.
Stop all the applications that are not absolutely needed.
if that doesn't work, reboot the computer, and only start the applications you need.

Related

batch script to delete all icons from all users' desktops

Currently looking for a way to delete all icons off of all user desktops. I have experimented until I made the following script that allowed me to delete all from a single user but without hard coding I won't be able to extend this to reach all users on a single PC.
#echo off
cd %%#
del C:\Users\%Userprofile%\Desktop\*.* /s /q
for /r %%# in (.) do rmdir %%# /s
cls
I am now looking to see if it is possible to extend this to multiple users without hard coding paths since I don't happen to know which user might be using the computer at the time.
Since you don't want to hard code path's, we can use the FOR to search for .ico files located in \Desktop for each user. The script bellow will search each users desktop, remove all .ico files, then prompt the user it has finished.
#ECHO OFF
#GOTO :search
:search
FOR /D %%G IN ("C:\Users\*") DO IF EXIST "%%~fG\desktop\*.ico" (
set correctDir=%%G\desktop
goto :foundFile
)
goto :finished
:foundFile
cd "%correctDir%"
del /S *.ico
goto :search
:finished
echo All Icons removed from users desktops!
pause
goto :eof
FOR /D iterates over all directories using the %%G variable. %%~fG expands to the full path to the directory in %%G.
IF EXIST checks if a file exists.
goto :eof exits the script
Extreme care must be taken when writing or working with scripts which are intended to delete files/folders. A single minor mistake can end up in a disaster.
For example this code: cd "MyFolder" & del /q *.* is extremely dangerous it delete all files from current directory with the assumption that previous cd command have changed the current directory to MyFolder, So in case of failure del command will delete all files from current directory which is not MyFolder. But this code is safe: cd "MyFolder" && del /q *.*. The del command will be executed only if the cd command have successfully changed the current directory to MyFolder.
Now back to your original problem of extending your code to wipe out 'Desktops' of all other users of the PC.
The first thing that should be considered is that a normal user typically does not have access to desktop folders of other users because of NTFS file system permissions which avoids non Administrators from accessing other users profile. So the resulting script will have to run with administrative privileges. Even running the script as Administrator does guarantee the success because each user can explicitly deny access to his/her user profile files/folders even to Administrators.
The other thing is while it is mostly the case that the desktop directory of each user is placed in a folder named Desktop located in the %USERPROFILE% directory e.g. C:\Users\John\Desktop but this is not always the case. In fact the desktop directory of each user can defined to be located anywhere and placed in a folder other than Desktop.
This is the case for other special folders other than Desktop.
So the correct approach is to first retrieve a list of user profiles from registry and then for each user profile query the location of user's desktop.
:: WipeDesktops.cmd
:: This script should be runned as Administrator to be able to access and delete the 'Desktop' contents of other users.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
:: To turn TestMode off It is highly recommended that to invoke the script with "/TestMode:Off" switch rather than manually setting TestMode to 0
set "TestMode=1"
set "DeleteCommandConfirm=rd /s"
set "DeleteCommandUnsafe=rd /s /q"
for /F "tokens=1,2 delims=:" %%A in ("%~1") do if /i "%%A"=="/TestMode" (
if /i "%%B"=="Off" (set "TestMode=0") else set "TestMode=1"
)
set "DeleteCommand=%DeleteCommandConfirm%"
if %TestMode% NEQ 0 (
echo Running in Test Mode
set "DeleteCommand=echo %DeleteCommand%"
) else (
set "DeleteCommand=2>nul %DeleteCommand%"
)
set "SID_Prefix=S-1-5-21-"
set "ProfileList=HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList"
set "ShellFoldersBase=Software\Microsoft\Windows\CurrentVersion\Explorer"
set "ShellFolders=%ShellFoldersBase%\Shell Folders"
set "UserShellFolders=%ShellFoldersBase%\User Shell Folders"
for /F "delims=" %%K in ('reg query "%ProfileList%" /k /f "%SID_Prefix%"') do (
set "ProfileKey=%%~K"
set "ProfileKey=!ProfileKey:HKEY_LOCAL_MACHINE\=HKLM\!"
if "!ProfileKey!" NEQ "!ProfileKey:HKLM\=!" (
set "ProfilePath="
for /F "tokens=2*" %%A in ('reg query "!ProfileKey!" /v "ProfileImagePath" 2^>nul') do (
set "ProfilePath=%%~B"
)
if defined ProfilePath if exist "!ProfilePath!\" (
set "Desktop="
set "SID=!ProfileKey:%ProfileList%\=!"
for %%S in ("%UserShellFolders%", "%ShellFolders%") do (
if not defined Desktop (
for /F "tokens=2*" %%A in ('reg query "HKU\!SID!\%%~S" /v "Desktop" 2^>nul') do (
set "Desktop=%%~B"
)
if defined Desktop (
REM %USERPROFILE% value is different for each user so it can not be expanded
for %%A in ("!ProfilePath!") do set "Desktop=!Desktop:%%USERPROFILE%%=%%~A!"
if not exist "!Desktop!\" set "Desktop="
)
)
)
if not defined Desktop set "Desktop=!ProfilePath!\Desktop"
REM Skip network paths
if "!Desktop:~0,2!" NEQ "\\" if exist "!Desktop!\" (
cd /d "!Desktop!" 2>nul && (
echo Removing 'Desktop' contents in !Desktop! ...
REM Since there is an open handle to the 'Desktop' folder, The contents of the folder will be removed but the folder itself remains.
%DeleteCommand% "!Desktop!"
)
)
)
)
)
For safety reasons it has 2 modes of operation:
Test Mode (the default): In this mode it only shows the commands along with the path that it can delete but no actual deletion will be performed
Normal Mode (invoke with /TestMode:Off switch) which will list and actually deletes the detected user desktops.
How it works
It first retrieves a list user profiles from registry key: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ProfileList each of them located under a registry key with a name that is equal to the corresponding user SID beginning with S-1-5-21-
for each SID key it queries the value of ProfileImagePath to obtain the location of the user profile directory.
Then it queries the location of user's desktop from two registry locations in the listed order:
HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
and uses the value of ProfileImagePath to resolve the value of %USERPROFILE% variable for that user which is typically present in the special locations under the User Shell Folders key
Finally if the location of user's desktop can not be determined through registry then the default path of %USEPROFILE%\Desktop is assumed.
What is missing?
Shared user desktop is not covered, which is commonly located at %ALLUSERSPROFILE%\Desktop or %PUBLIC%\Desktop depending on windows version.
But the definite location can be obtained from these registry keys:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
So I'll leave it to you to do the rest and complete the missing part.

appending date with filename using batch scripts

I am trying to set a housekeeping for different type of file. PFB scenario.
I have below set of files in a network path(\NAS.domain.local\data\Arasan)
test.sql
test1.txt
test2.log
I am trying to rename the files as shown below and move the files to .\Archive\ directory
Test_15-12-2016_151428.sql
Test1_15-12-2016_151428.txt
Test_15-12-2016_151428.log
([Filename]_DD-MM-YYYY_HHMISS.[ext])
I have built the below batch script.
#echo ON
SET Log_Path=\\NAS.domain.local\data\Arasan
SET Script_Path=C:\Scripts
REM ###########################################REM
REM ## Do make any changes to the text below ##REM
REM ###########################################REM
cd %Script_Path%
pushd %Log_Path%
dir /b /a-d > %Script_Path%\list.txt
set HH=%TIME:~0,8%
for /F %%A in (%Script_Path%\list.txt) do (
setlocal EnableExtensions EnableDelayedExpansion
set ffname=%%A
set "fname=%%~nA"
set "fext=%%~xA"
ren !ffname! !fname!_%DATE%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%!fext!
endlocal
)
del %Script_Path%\list.txt
move *.* Archive\
popd
exit
Now my issue is it is working perfectly in my machine but when I transfer this to server and execute. It is
throwing "The syntax of the command is incorrect." Error.
And it is moving the files without renaming. As for as i know, file name and extension is not being assigned to the variable properly in below part
set ffname=%%A
set "fname=%%~nA"
set "fext=%%~xA"
Server OS: Windows server 2008 R2 Standard(SP1)
Can anyone please help me. Thanks a lot.
Here is the part of the code you should be using to get a consistent date and time output:
For /F "Skip=1" %%A In ('WMIC OS GET LocalDateTime') Do For %%B In (%%~nA
) Do Set "DTS=%%B"
Set "DTS=_%DTS:~6,2%-%DTS:~4,2%-%DTS:~,4%_%DTS:~-6%"
Echo( [%DTS%]
Pause
Just incorporate this into the rest of your code…

Batch file to copy list of files including subdirectories

I often have to track down files at work, pulling a hundred or so out of a list of a thousand, so I created a batch file that would copy the files in a location that are listed in a csv in the batch files directory and then paste them in a folder on my desktop.
This worked, but I often have to do this for hundreds of files across a dozen or so directories, so I tried to modify it to include subdirectories. I'm having an issue getting it to work and I was wondering if the excellent people at StackOverflow could help. Thanks!
#echo on
set theDest="%USERPROFILE%\Desktop\Batch Copies %date:/=%"
set /p MY_TEXT=<FileList.csv
echo.%MY_TEXT%
set MY_TEXT=%MY_TEXT:"",""=,%
echo.%MY_TEXT%
if not exist %theDest% md %theDest%
pause
for /R %MY_TEXT% %%G IN (.) do (
for /F "skip=1 delims=" %%f in (FileList.csv) do (
if exist "%MY_TEXT%\%%f.*" (
copy "%MY_TEXT%\%%f.*" %theDest%
) else (
if exist "%MY_TEXT%\%%f" (
copy /R "%MY_TEXT%\%%f" %theDest%
) else echo "%MY_TEXT%\%%f" does not exist && echo 0 file^(s^) copied. && echo ERROR: %%f not found && echo. && pause)
)
)
echo. && echo. && echo Process Completed. &&echo.
pause
Part of the problem is I was just getting into batch when I wrote this and then left it and am trying to come back and figure out how everything works so I've probably messed it up more ways than one.
So the FOR loop has a /R option which will run the same command across all subdirectories.
In your case, I think you want:
for /R %%a in (.) do call :MyCopyFunction %%a
exit /B
:MyCopyFunction [%1 is the current directory]
echo My Current directory is %1
[Do All your code here, using %1 as the current directory]
exit /B
I don't understand what your script is doing in detail, so you still have to fill in the details.
But this shows you how to traverse the entire directory structure.

How to use batch job to add the file "create date" into all the files in a directory?

I have a folder that gets a new file added everyday to the folder with the same file name but incremental extension such as .001, .002, .003, etc. However, if there's no file within the folder it starts at .001 again.
The problem is they are all named the same and if I move them to another folder to archive them it would just overwrite the same file over and over again. I could create a folder each day with the date with only one file in it, but that seems a bit redundant.
Is there a way to look at the create date of each file and rename it to the create date?
I've gotten this far, but it looks like for this situation I have to use a static file name, how to loop through the entire directory?
SET filename = C:\test.001
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
rename c:\test.001 C:\test_%filedatetime%.txt
move C:\*.txt C:\archive\
this provides the correct sort order:
#echo off &setlocal disableDelayedExpansion
set "startfolder=%userprofile%\test"
cd /d "%startfolder%"
for %%a in (*) do (
for /f "delims=." %%b in ('wmic datafile where "name='%startfolder:\=\\%\\%%~a'" get lastmodified^|find "."') do (
echo(ren "%startfolder%\%%~a" "%%~b.txt"
)
)
Remove echo to get it working.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "targetdir=c:\sourcedir"
SET "destdir=c:\destdir"
PUSHD "%targetdir%"
FOR %%a IN (*.*) DO (
SET "timestamp=%%~ta"
SET "timestamp=!timestamp:/=_!
SET "timestamp=!timestamp::=_!
SET "timestamp=!timestamp:.=_!
SET "timestamp=!timestamp:,=_!
SET "timestamp=!timestamp: =_!
ECHO MOVE "%%a" "%destdir%\%%~na.!timestamp!"
)
GOTO :EOF
This should work with any file in the nominated target directory where the name does not include ! or ^.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
The gymnastics around timestamp are intende to replace /: with _ since these are illegal filename characters. Space., are similarly replaced - they're legal but often painful.
If you want the destination filename to be name.003.timestamp, remove the ~na from the destination name.
Try like this :
SET $path=The_path_who_contain_the_FILES
FOR /F "DELIMS=" %%f IN ('dir "%$path%" /a-d/b') DO (
SET filedatetime=%%~tf
move "%%~dpnxf" "C:\archive\test_%filedatetime%.txt")

Batch file to delete selected files

In most modern systems, the system will automatically create extra files that are unnecessary. How can I create a .bat file that makes use of a checklist to delete any file that isn't on it?
This would be useful for removing automatically generated backup files, plot logs, error logs, etc. in the customization files I have created.
Try this, make sure to set SEARCHDIR to the real dir, and populate keep.txt with the files you want to keep, 1 file per line, use the full path including the dir. If you don't want to use the dir, adjust the DIR /S /B command so it outputs the same format as what is in your keep.txt
#echo off
setlocal enabledelayedexpansion
set KEEPFILES=keep.txt
set SEARCHDIR=.\test_folder
SET /a KEEPTHISFILE=2
FOR /f "tokens=*" %%A IN ( 'DIR /S /B %SEARCHDIR%\*' ) DO (
SET /a KEEPTHISFILE=0
for /f "tokens=1,* delims=¶" %%B in ( '"type %KEEPFILES%"') do (
if "%%A"=="%%B" SET /a KEEPTHISFILE=1
)
if "!KEEPTHISFILE!"=="0" (
echo "deleting %%A"
del /f %%A
)
)
Make a file called 'deletestuff.bat' (or whatever you want it to be called, as long as it is a .bat). Next, fill it with:
rm *.tmp
rm *.blah
Where .tmp, and .blah are the extensions of the files that you would like to delete (they might be .log, for instance). Test it first by copying a sample of files into a new folder and running the new .bat there, just to make sure it doesn't delete important things.

Resources