Batch Script Loop That Skips Matched Values - windows

I have an existing script that loops through a list of folders, and deletes a file from each folder found. I want the script to skip specific folders in the list based on name.
Here is the existing script:
for /d %%F in (c:\users\*) do del "%%F\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\f01b4d95cf55d32a.automaticDestinations-ms" /s /q
In this case, I would want it to skip the "admin" folder found "c:\users".

The code below is designed for Windows 10, as your task is for resetting the Quick Access Pinned Folders in its File Explorer.
The code already ignores the 'Special' PC accounts, that includes, but may not be limited to, Administrator, DefaultAccount, Guest, and WDAGUtilityAccountdefault.
If you have other named accounts you want to exclude from this task, you could insert them at line 7 between ' and " using the following syntax: And Name='firstName' Or Name='anotherName' Or Name='additionalName'
For example:
"LocalAccount='TRUE' And Name='admin' Or Name='john' Or Name='jane'"
Nothing else should be modified, added or removed for testing purposes.
#Echo Off
SetLocal EnableExtensions
Set "SubPath=AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations"
Set "FileName=f01b4d95cf55d32a.automaticDestinations-ms"
For /F Tokens^=6^ Delims^=^" %%G In ('
%SystemRoot%\System32\wbem\WMIC.exe UserAccount Where
"LocalAccount='TRUE'"
Get SID /Format:MOF 2^>NUL') Do For /F Tokens^=6^ Delims^=^" %%H In ('
%SystemRoot%\System32\wbem\WMIC.exe Path Win32_UserProfile Where
"SID='%%G' And Special!='TRUE' And LocalPath Is Not Null" Get LocalPath
/Format:MOF 2^>NUL') Do Del /A /F "%%H\%SubPath%\%FileName%" 2>NUL
The code may look complex, but its benefits are that it ignores 'Special' accounts, and it does not limit their local profile paths to C:\Users. Not every user has to have their profile directory in the default location, so this determines that location without making such assumptions.
I have also modified your Del command options because the file you are wanting to delete is not located one or more times within the tree, negating /S, and as you are not using a global wildcard, you do not need the /Q option either. I have included the /A and /F options just in case the file has problematic attributes, just to improve the chances of successful deletion.
Please be aware that if your task involves removing files from another user's profile tree, then the invoker of the task must have the required permissions to do so.

Related

How to include system variable in batch file inside FOR loop ? also escaping the ! and % sign inside variable?

lets say i have a list file contains folder names that i want to delete periodically based on a list,
currently using this batch file which don't work as i expected :
setlocal enabledelayedexpansion
for /F "tokens=2* delims==" %%x in ('findstr/brc:"foldertodelete" garbagefolderlist.txt') do (
set "foldertodelete=%%x"
set foldertodelete=!foldertodelete:"=!
set foldertodelete=!foldertodelete:%%=^!!"
echo !foldertodelete!
if exist !foldertodelete! (
echo deleting !foldertodelete!
rmdir /s /q !foldertodelete!>nul
)
)
endlocal
inside garbagefolderlist.txt :
foldertodelete="%programfiles%\blablabla"
fodlertodelete=%systemroot%\blablabla
foldertodelete="C:\Temp"
foldertodelete=D:\Temporary files\here
notes about the list file (garbagefolderlist.txt) :
1. folder names may contains double quotes or not, so i want to dynamically eliminate the double quotes inside batch file
2. folder names may be plain or using system variable or not like %systemroot%, etc
3. folder names may contains spaces
If all you want to do is delete the folders listed in that text file you only need one single line of code. You need to use the CALL command to get the double variable expansion that you require. You don't even need delayed expansion at all.
for /F "tokens=2* delims==" %%x in ('findstr /bc:"foldertodelete" garbagefolderlist.txt') do call rmdir /s /q "%%~x" 2>nul
Here is the execution of your script on my system. I created a folder in Program Files and I also have a Temp folder on the C: drive. The line in your file with %systemroot% will not be chosen because you have a typo on that line. So the script will only attempt to process three lines from your input example.
I have added the echo to the code and removed the error dump to nul so that you can see all the output.
#echo off
for /F "tokens=2* delims==" %%x in ('findstr /bc:"foldertodelete" garbagefolderlist.txt') do (
call echo %%~x
call rmdir /s /q "%%~x"
)
And here is the output of that code.
C:\BatchFiles\SO\71120676>so.bat
C:\Program Files\blablabla
Access is denied.
C:\Temp
D:\Temporary files\here
The system cannot find the path specified.
So lets break down that output.
You can see that the %programfiles% variable is expanded as it echo's the folder name correctly but the folder cannot be deleted because I am not running from an elevated cmd prompt as Administrator. So that folder cannot be deleted.
The temp folder displays correctly and is deleted.
The last directory does not exist on my system as I don't have a D: drive so the system reports that it cannot find the path. If standard error was still being redirected to the NUL device you would not see the error which is why I don't bother with checking if a folder exists before I delete it.

Batch script to fetch and play specific video file

I am having trouble with creating a batch file which then can be mapped to a keyboard shortcut, The basic's of the script is it asks for the season, episode and shot and finds it via that input in the directory however I having trouble with the fact that some folders have specific names at the end and I cant understand how to go about creating wild cards.
#echo off
set /p Series=Series:
set /p Episode=Episode:
set Series=00%Series%
set Episode=00000%Episode%
set Episode=%Episode:~-3%
rem open up review
set Path="P:\projectName\06_review\series_%Series%\sr%Series%_ep_%Episode%"
for /f "tokens=*" %%a in ('dir /A:-D /B /O:-D /S %Path%') do set NEW=%%a&& goto:n
:n
start %NEW%
So far this is doing well grabbing the latest file but once it needs to grab a folder that has more characters after \sr%Series%_ep_%Episode% it fails, but what is the best way to create wild cards for any possible string after the matching input?

How is it possible to get Windows default user profile path via CMD?

Windows default user profile is usually %SystemDrive%\users\default but its real location is not an environment variable but it can be useful to have it.
Default user profile path can be detected by system registry query like that
#echo off
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CurrentVersion\ProfileList" /v "Default"') do set "defaultuserprofile=%%b"
echo %defaultuserprofile%
pause
But we get the value %SystemDrive%\Users\Default where %SystemDrive% is not converted to C: (or other letter) so environment variable %defaultuserprofile% can not be used as normal environment variable path for file operations.
Alternative variant can be something like
#echo off
cd /d "%public%"
cd ..\
set usersdir=%cd%
set defaultuserprofile=%usersdir%\default
echo %defaultuserprofile%
pause
But it seems to be not so good.
So how is it possible to get Windows default user profile path via CMD?
Don't your really want %PUBLIC%, which is C:\Users\Public? At least that's closest equivalent on Windows 10 to a "Default" folder.
#echo off
setlocal
set "defaultuserprofile="
for /f "tokens=1,2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v "Default"') do (
if "%%~A" == "Default" call set "defaultuserprofile=%%C"
)
echo "%defaultuserprofile%"
pause
The type of the data is REG_EXPAND_SZ. To expand the %SystemDrive% embedded in the string, use call set. call causes another parse of the command so that set assigns C:\ instead of %SystemDrive%.
Like the 2nd OP code, which is not as reliable as the reg query:
#echo off
cd /d "%Public%\..\Default" || exit /b 1
echo "%cd%"
pause
If you want to view the Default folder and other hidden folders in the Users directory, use:
dir /a:h
Output is the symlink named All Users, the folder named Default and the symlink named Default User on Windows 10 v1903.
Firstly, just to mention the purpose of the Default user profile is as the basis for all new user profiles. Therefore it should be used only to configure applications, settings and customizations for each future new user account on the PC. (modifications within it do not propagate to existing users).
The following method is similar to the existing answer, in that an additional expansion is used to cater for any variables within the contained data string. Please note that the value type of the data is by default REG_EXPAND_SZ, but it can also be of type REG_SZ, (the expand type is only necessary if the string contains a variable).
#Echo Off
Set "RKey=HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList"
Set "RVal=Default"
Set "ProfilePath="
For /F "Tokens=2*" %%G In (
'""%__APPDIR__%reg.exe" Query "%RKey%" /V "%RVal%" 2>NUL|"%__APPDIR__%find.exe" /I "%RVal%""'
)Do For /F "Tokens=*" %%I In ('Echo("%%~H"')Do Set "ProfilePath=%%~I"
If Not Defined ProfilePath Exit /B 1
Rem Your code using "%ProfilePath%" goes below here
Echo "%ProfilePath%" & Pause
I have Remarked a line with comment, which can be optionally omitted, and provided an example line below it for demonstration purposes, please modify that as necessary.
The code uses full paths for all external commands, (via a special variable, %__APPDIR__%, which will always point to their correct location). I have done that in order to remove any reliance on the content of the editable environment variables %PATH% and %PATHEXT%, (deliberate, or accidental, modification of those two environment variables could otherwise break the code).

Finding and removing ._ files with batch file

I'm trying to find and remove ._ files using a batch file. The files were copied from a Mac onto a PC.
ECHO Again!
DIR /B /A-D /ON /S ._* 2>nul
DEL /S ._*
It will list them but won't delete them. What's up with that?
D:\projects\._my_colours.txt
D:\projects\._png_vs_jpeg.jsx
D:\projects\._rainbow_screen_sizes.jsx
D:\projects\._save_it_mac.jsx
D:\projects\._some_text.txt
Could Not Find D:\projects\*._
I can delete them by hand, however, I just want to know where I'm going wrong.
The files carried over from MAC should have the archive and hidden properties only, so to ensure that you only pick those up, I'd suggest that you only select those for deletion. The DEL command has an /A option which selects the files to delete based upon their attributes. As soon as you use the /A option it picks up all attributes as if you'd selected them. If you do not exclude any attributes using the - prefix it will delete them all, (except for Read-only, unless you've included the /F option too). For example DEL /F /A ._* will delete those with Read-only, System, Hidden, Archive, unIndexed and reparse points (L). In this case your wanting those with just H and A, so to exclude all others you should use their exclusion prefix. Additionally as ._* is a global wildcard, you'll probably want to use the /Q option to prevent a prompted request for confirmation.
Del /S /Q /A:HA-R-S-I-L ._*
As a note-worthy point, if you have MAC directories transferred over too, those may have file partners. For example the ready for archiving hidden directory .Trashes will be partnered with a ready for archiving hidden file named ._.Trashes along side it. These would be deleted using the wildcard above, so if you have those type of directories, and you're not removing those too, you may wish to use a different method in order to preserve their partner files.
You could do that from the command-line via a for-loop. (From a batch-file you need to escape the % characters with another, %%):
For /F "Delims=" %A In ('Dir /B /S /A:HA-D-R-S-I-L ._* 2^>NUL') Do #If Not Exist "%~dpxA\" Del /A "%A"
In this case, the DIR command selects all of the files using the same methodology as the DEL command used, and passes those files as metavariables to the Do portion. We then delete each passed file, as long as it isn't a partner to a directory. We can do that using the /A option alone, because DIR has preselected only those we want. To perform the check for a partner, we just use a simple IF NOT EXIST statement, remembering that when checking for the existence of a directory, we use a trailing backslash. The check is performed by expanding each metavariable, %A to its drive:, \path\ and .extension using %~dpxA. The expansion of D:\MyDirectory\SubDirectory\._.Trashes would return D:\MyDirectory\SubDirectory\.Trashes so the check performed will effectively be If Not Exist "D:\MyDirectory\SubDirectory\.Trashes\". If that directory does not exist then it is deleted using Del /A "D:\MyDirectory\SubDirectory\._.Trashes".
System files! D'oh!
DEL /AH /S ._*

How to write a batch file to delete multiple specific files from different paths?

Each time before I start debugging, I need to delete some specific files from different paths. It's a tiresome process as I do it like a million times in a day. So I want to write a batch file that deletes all those at once without prompting.
The first path is
C:\Users\irem\AppData\Roaming\JDeveloper\systemx\DD\servers\DefaultServer\tmp\
I want everything under this temp folder gone. Without the temp folder itself, of course.
The second path is
C:\Users\irem\AppData\Roaming\JDeveloper\systemx\o.j2ee\drs\
I again want everything under this drs folder gone. Again without the drs folder itself, of course.
The third path is
C:\Users\irem\AppData\Roaming\JDeveloper\systemx\
This time I want to delete only the files with .lok extension under the systemx folder.
I tried to write something like this:
del "C:\Users\irem\AppData\Roaming\JDeveloper\systemx\DD\servers\DefaultServer\tmp\*.*?" /s
& del "C:\Users\irem\AppData\Roaming\JDeveloper\systemx\o.j2ee\drs\*.*?" /s
& del "C:\Users\irem\AppData\Roaming\JDeveloper\systemx\*.lok"
However it doesn't meet my expectations, it doesn't work.
I appreciate all the help. Thank you very much.
Perhaps something like this would do what you want:
#Echo Off
Set "srcPath=%AppData%\JDeveloper\systemx"
Set "tmpPath=DD\servers\DefaultServer\tmp"
Set "drsPath=o.j2ee\drs"
CD /D "%srcPath%" 2>Nul || Exit /B
Del /F /Q /A *.lok
For /D %%A In ("%tmpPath%\*" "%drsPath%\*") Do (RD /S /Q "%%A"
Del /F /Q /A "%%A\*.*")
I have used the paths you provided in your question, if those have changed, you can alter them by editing lines 2, 3 and 4 as necessary.

Resources