I work in a domain environment where devices store local user profiles in the C:\Users folder.
I would like to develop a batch files for users to be able to run to remove files (user profiles) that have not been modified in 90 days. I do need an exemption for any file that ends in .OA or .SA
I had this, but it was started to look in C:\Users\All Users however, that is not one of the directories available to delete.
ForFiles /p "C:\Users" /s /d -90 /c "cmd /c del #file"
Any assistance would be greatly appreciated.
I have decided to post this single line batch-file as a potential solution for isolating the active user accounts you wish. However I will add, that whilst I have used an improved version of your intended ForFiles command, I do not advise that you use it in a real environment. I say that because, depending upon the age of the user account, there will very likely be a great many files within those directory trees, which are needed. Just because a file has not modified, within a certain timespan, it does not mean that it can be deleted. For that reason I have used Echo #Path at the end of the command line, instead of your submitted Del #File. If you are happy to delete everything which is returned from my code above, feel free to make your deletion replacement.
#For /F Tokens^=2^ Delims^=^" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe UserAccount Where "AccountType = 512 And LocalAccount = 'TRUE' And SIDType = 1 And Status = 'OK'" Assoc:List /ResultClass:"Win32_SID" 2^>NUL ^| %SystemRoot%\System32\findstr.exe "__R"') Do #For /F Tokens^=6^ Delims^=^" %%H In ('%SystemRoot%\System32\wbem\WMIC.exe Path Win32_UserProfile Where "LocalPath Like '%SystemDrive%\\Users\\%%' And SID = '%%G' And Special = 'FALSE'" Get LocalPath /Format:"MOF" 2^>NUL') Do #%SystemRoot%\System32\forfiles.exe /P "%%H" /S /D -90 /C "%SystemRoot%\System32\cmd.exe /D /C \"If #IsDir == FALSE If /I Not #Ext == \"OA\" If /I Not #Ext == \"SA\" Echo #Path\""
Related
I'm starting to learn how to use the CMD in Windows. And I have a directory full of documents with names like "Document_1.txt", "Document_5.txt" etc... (All with Document_#.txt but there's no pattern in the numbers).
I want to move each file to a folder named "Text_#" and change the name of the file to "text_#.txt". How can I do that?
My attempt is this (simple) batch file (actually I think I don't even need to create a batch file, but was easy to do this way.)
#ECHO OFF
FOR /L %%i IN (1,1,24) DO (
FORFILES /M *.txt /C "cmd /c IF #fname==Document_%%i (MD Text_%%i) & (MOVE #file Text_%%i\text_%%i.txt)"
The problem is that the IF command never returns true, although when writing ECHO #fname it prints "Document_#", so I suppose that even if what I see is the same there is some difference that I cant see using the ECHO command.
Anybody could give me some solution to this problem?
In my opinion the simplest way is to forget about using the ForFiles command for this, and use a For /F loop instead. To ensure that only the files with a .txt extension whose basename ends with _# or _##, (where # represents an integer), use the Dir command and filter its results with the help of FindStr. Then you can use MD to make the directories if it don't already exist and move the files into it, renaming them with their new name.
From the cmd with the current directory as that holding your files:
For /F "Tokens=1,* Delims=_" %G In ('Dir /B /A -D Document_??.txt ^| %__AppDir__%findStr.exe /I "_[0123456789]*\.txt$"') Do #If Not Exist Text_%~nH (MD Text_%~nH) & Move /Y %G_%H Text_%~nH\text_%H 1>NUL
If you want to do that from a batch-file instead, also within the same current directory:
#For /F "Tokens=1,* Delims=_" %%G In (
'Dir /B /A -D Document_??.txt ^| %__AppDir__%findStr.exe /I "_[0123456789]*\.txt$"'
) Do #(
If Not Exist Text_%%~nH MD Text_%%~nH
Move /Y %%G_%%H Text_%%~nH\text_%%H 1>NUL
)
The above answers assume either one or two digits at the end of the file basenames, (as you were limiting yours to numbers from 1 to 24 inclusive) I have also left out quoting because your provided names didn't warrant it. If those were not truly representative, you'll need to introduce those as necessary and make any other changes which were outside of the question posed.
I have two parameters. It was suggested that this is a duplicate question, but I want to specify a minimum age AND a minimum number of files to be kept. I'm not sure how to combine those parameters.
I have a batch file which includes this code:
#echo off
set "backupDir=[BACKUP DIR PATH HERE]"
copy /Y "[PATH OF FILE TO BE COPIED]" "[PATH WHERE BACKUP IS SAVED]"
for /f "skip=4 delims=" %%a in ('dir "%backupDir%\" /b /a-d /o:-d') do del "%backupDir%\%%a"
It creates a backup of a database and deletes everything except the four most recent instances. What I want is to make sure that if the batch file is run more than once in a day, I don't end up deleting the old files and end up with four copies of what would essentially be the same backup.
How can I specify that the file must be at least "N" days old before deletion?
It might be better to have something that limits the file from running again if it hasn't been at least 24 hours since the last time. But I don't know how to do that either.
If I understand correctly, you want to delete all but the newest four backups, but only if they have got a minimum age (or, more precisely, if they have been modified earlier than a certain number of days ago).
The following code does exactly that:
pushd "%backupDir%" || exit 1
rem // Iterate files but skip the four ones that have been modified most recently:
for /F "skip=4 delims=" %%F in ('dir /B /A:-D /O:-D "*.*"') do (
rem // Verify whether the last modification date is at least seven days ago:
for /F "delims=" %%I in ('
2^> nul forfiles /P "%%~dpF." /M "%%~nxF" /D -7 /C "cmd /C echo #path"
') do (
ECHO del "%%I"
)
)
popd
Remove the upper-case ECHO after having verified the correct output.
use forfiles
forfiles /P "%backupDir%" /M *.* /D -10 /C "cmd /C echo #path"
You can change the number of days where -10 is.
Change echo to del only when you are 100% sure it echo's the correct files you want to delete.
You can be more specific with your file types by replacing *.* with your file extension or actual file name. i.e *.MYD or backup_db* etc.
For more info run forfiles /? from cmd.exe
To add the line above to your script, simply replace this line:
for /f "skip=4 delims=" %%a in ('dir "%backupDir%\" /b /a-d /o:-d') do del "%backupDir%\%%a"
with the forfiles line.
I am trying to set up a batch program that will go to the different computers on my network (from .txt file) and then delete files from the users on the that PC, and then empty the recycle bin. I've got the second part working so I can delete files from multiple users on a PC, but I can't get it to look at other PC's. I was hoping someone might point out what I'm missing here. Here is what I have so far:
#ECHO off
Setlocal EnableDelayedExpansion
FOR /F "delims=" %%i IN (test.txt) DO (
for /f %%a in ('dir /B /AD C:\Users') do (
REM for /f "tokens=*" %%a in (userlist.txt) do (
if exist "C:\Users\%%a\" del /S /Q "C:\Users\%%a\AppData\Local\Lotus\Notes\Data\workspace\logs"
if exist "C:\Users\%%a\" del /S /Q "C:\Users\%%a\AppData\Local\Google\Chrome\User Data\Default\*"
if exist "C:\Users\%%a\" del /S /Q "C:\Users\%%a\AppData\Local\Microsoft\Windows\Temporary Internet Files"
)
RD %systemdrive%\$Recycle.Bin /S /Q
)
pause
Anybody got any pointers?
You need to use UNC paths.
\\server\sharename\folder\file.ext
You can get a list of computers with
for /f "skip=3" %A in ('net view ^| findstr /C:"\\"') do Echo %A
All computers have a share for admins only called C$ that is the C drive (and D$ etc). $ makes it hidden. So
for the local computer via UNC
del /S /Q "\\127.0.0.1\C$\User\username\AppData\Local\Lotus\Notes\Data\workspace\logs"
Also there is no point to If Exist, just delete it - it will work or not. If you care if it worked or not you test the return value If errorlevel 1 echo error. You are causing extra disk access and network traffic. In programming we do and test not test and do.
You can also run a batch on the other computer.
wmic /node:"#Computerlist.txt" process call create "c:\\batchfile.bat"
Note \\ in paths. C:\\batcfile.bat is C: on the remote computer. This allows you to only use one for loop in your batchfile. You copy the batch file with copy. Net View can generate the computer list although you have to remove \\
for /f "tokens=1 delims=\" %A in ('net view ^| findstr /C:"\\"') do Echo %A
I am trying to write a batch file that removes/deletes different user(s) folders in C:\users that are older than 210 days.
I tried this
forfiles /p C:\users /d -210 /c "cmd /c del #file"
However this command deletes the shortcut of the current user as well as those shortcuts are older than 210 days.
Can I get the batch file to only remove the entire folder if the last modified date of the content is older 210 days
Also can I specify the starting name of the folder to be deleted(the users starts with PDC), as I fear it may delete some of the important hidden document of a computer, as this batch file will be run on an administrator account.
Any help is appreciated thanks
First run robocopy in list-only mode and if there were no files newer than the specified age proceed with the actual delete operation:
#echo off
set AGE=2
set EXCLUDE="Public" "admin1" "admin2"
for /d %%D in (C:\users\*) do (
echo %EXCLUDE% | find /i """%%~nD""" >nul
if errorlevel 1 (
set too_new=0
robocopy "%%D" "%%D" /L /v /s /xjd /minage:%AGE% | findstr /r /c:"^. *too new" >nul
if errorlevel 1 (
echo Deleting %AGE% days old %%D
rd /s /q "%%D"
)
)
)
pause
Don't forget to do a test run first by commenting out the rd line: put rem and a space before it.
Notes:
/L = list-only mode, no copying performed
/V = verbose mode, report files skipped for various reasons, e.g. the "too new" we look for
/S = look in subdirectories
/xjd = don't follow junction points for directories, useful if those point to an unavailable device
^. *too new regular expression in findstr lists lines beginning with a tab character followed by lots of spaces and then too new.
I'm kind of struggling with the following search.
I need to look for files which are misplaced in wrong folders. I have the following testing structure (in reality it is hudreds of folders):
C:\test2\John\John_phone.txt
C:\test2\Mary\John_address.txt
C:\test2\Mary\Mary_address.txt
C:\test2\Mary\Mary_phone.txt
C:\test2\Mary\Peter_address.txt
The files John_address.txt and Peter_address.txt are misplaced in Mary's folder. I want to check Mary's folder for any misplaced files and list them in a separate log file. So for the example above the log would contain the names (paths) of the two misplaced files, The deciding identifier is the person's name. I have this piece of code:
#echo off
cls
set /p name="Specify the name: "
::forfiles /p "%CD%\%name%" /s /m *.* /c "cmd /c echo #path">>log.txt
forfiles /p "%CD%\%name%" /s /m "| findstr /i /v "\*%name%*"" /c "cmd /c echo #path">>log.txt
pause
The commented line for forfiles works (lists all files in the folder), so I have an issue with findstr: ERROR: Files of type "| findstr /i /v *Mary*" not found.
The /v switch with findstr should find all files that do not contain the specified name, but obviously I'm doing something wrong while using it as input for forfiles.
I don't want to use the dir command since it lists additional information and I need to integrate the output into larger log file (I need to get only the path of the misplaced file).
Any help is appreciated.
Thanks.
Edit: Would it be easier to write the code if the correct file name would be fixed like this?
All_data_%NAME%_new.txt
The stuff before and after the name would be fixed and this format of the file name would be the only correct option, so anything else would have to be reported.
For a simple solution
#echo off
setlocal enableextensions disabledelayedexpansion
set "rootFolder=c:\test2"
( for /d %%z in ("%rootFolder%\*"
) do for %%y in ("%%~fz\*"
) do for /f "tokens=1 delims=_" %%a in ("%%~ny"
) do if /i not "%%~nxz"=="%%a" echo %%~fy
) > log.txt
This will iterate the files under each of the folders testing if their name starts with the same string that the folder name.
edited the original proposed solution does not work as intended, so, removed
edited - as the name of the file has not a fixed format, and the name of the folder can be in any place, this can be used
#echo off
setlocal enableextensions disabledelayedexpansion
set "rootFolder=c:\test2"
rem create a temporary file to hold the patterns to match against the list
rem of files to determine if it is correctly placed
set "patterns=%temp%\%~nx0.%random%.tmp"
> "%patterns%" (
for /d %%a in ("%rootFolder%\*") do echo(\\%%~nxa\\[^^\\]*%%~nxa[^^\\]*
)
rem Get the list of files, and filter to only get those that do not match
rem the generated patterns
dir /s /b /a-d "%rootFolder%\*" ^
| findstr /r /i /c:"%rootFolder:\=\\%\\[^\\]*\\." ^
| findstr /r /i /e /v /g:"%patterns%" ^
> log.txt
rem Patterns file is no longer needed
del "%patterns%" >nul 2>nul
this should help provided that comparison is case sensitive
for /f "delims=.'_\ tokens=2,3,*" %%a in ('forfiles /s /m *.txt /c "cmd /c echo #relpath"') do if NOT "%%a"=="%%b" #echo "%%a\%%b_%%c