Created
April 16, 2015 20:02
-
-
Save stefanprodan/846f6bd233678fd05e33 to your computer and use it in GitHub Desktop.
Solution to delete millions of files on windows, after starting the script kill explorer.exe process. Script source http://superuser.com/a/892412/376959
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ECHO OFF | |
SETLOCAL EnableDelayedExpansion | |
IF /I "%~1"=="timestamp" ( | |
CALL :ECHOTIMESTAMP | |
GOTO END | |
) | |
rem directory structure to delete | |
SET "DELETE=c:\_delete\???<<<change this>>>???" | |
rem primary list of discovered files to delete | |
SET "LIST=delete-list.txt" | |
rem base path for sub-lists | |
SET "LISTBASE=.\delete-list" | |
SET "TITLE=Batch Delete Process" | |
rem specifies number of batch delete processes to spawn | |
SET FORKS=4 | |
rem when set to 1, use PowerShell for list building and delete. Definitely improves time to build fork sublists | |
SET POWERSHELL=0 | |
rem specifies max files to delete when greater than 0 | |
SET MAXDEL=1000000 | |
rem prompt for confirmatoin | |
SET /P CONT=About to delete all files and directories from !DELETE!. Continue (Y/N)? | |
IF /I NOT "!CONT!"=="Y" EXIT /B | |
CALL :ECHOTIMESTAMP | |
ECHO Accumulating list of files to delete... | |
dir /b /s "!DELETE!" > "!LIST!" | |
FOR /F "delims=" %%c IN ('type "!LIST!" ^| find /C ":"') DO SET "COUNT=%%c" | |
ECHO Discoverd !COUNT! files and directories to delete. | |
IF %MAXDEL% GTR 0 IF !COUNT! GTR %MAXDEL% ( | |
SET COUNT=%MAXDEL% | |
ECHO Limiting files/directories deletion count to !COUNT! | |
) | |
CALL :ECHOTIMESTAMP | |
ECHO Preparing !FORKS! delete processes... | |
SET /A LIMIT=!COUNT!/!FORKS! | |
IF !POWERSHELL! EQU 1 ( | |
SET SKIP=0 | |
FOR /L %%n IN (1,1,!FORKS!) DO ( | |
SET "CURRENT=!LISTBASE!-%%n.txt" | |
SET "LIST[%%n]=!CURRENT!" | |
DEL /f /q "!CURRENT!" > nul 2>&1 | |
IF %%n EQU !FORKS! SET /A LIMIT+=!FORKS! | |
SET CMD=type \"!LIST!\" ^| select -first !LIMIT! -skip !SKIP! | |
powershell -command "& {!CMD!}" > "!CURRENT!" | |
SET /A SKIP+=!LIMIT! | |
) | |
) ELSE ( | |
rem significantly slower but no PowerShell. | |
SET L=1 | |
SET N=!LIMIT! | |
SET C=0 | |
FOR /F %%f IN (!LIST!) DO ( | |
IF !C! LSS !COUNT! ( | |
IF !N! GEQ !LIMIT! ( | |
SET "CURRENT=!LISTBASE!-!L!.txt" | |
SET "LIST[!L!]=!CURRENT!" | |
DEL /f /q "!CURRENT!" > nul 2>&1 | |
SET /A L+=1 | |
SET /A N=0 | |
) ELSE ( | |
SET /A N+=1 | |
) | |
ECHO %%f >> "!CURRENT!" | |
) ELSE ( | |
GOTO ENDLIST | |
) | |
SET /A C+=1 | |
) | |
) | |
:ENDLIST | |
CALL :ECHOTIMESTAMP | |
ECHO Forking !FORKS! delete processes... | |
FOR /L %%t IN (1,1,!FORKS!) DO ( | |
SET "CURRENT=!LIST[%%t]!" | |
IF !POWERSHELL! EQU 1 ( | |
SET "TAB= " | |
SET BLANK=!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB! | |
SET BLANK=!BLANK!!BLANK!!BLANK!!BLANK! | |
SET DEL_CMD=del -force -recurse -ea SilentlyContinue -path \"$_\" | |
SET $W_CMD=$w=$Host.UI.RawUI.WindowSize.Width | |
SET $S_CMD=$s=\"$_\";$i=[math]::max^(0,$s.length-$w^);$s=$s.substring^($i, $s.length-$i^);$s=\"$s !BLANK!\";$s=$s.substring^(0,[math]::min($w,$s.length^)^) | |
SET ECHO_CMD=Write-Host \"`r$s\" -NoNewLine | |
SET CMD=type \"!CURRENT!\" ^| %% {!DEL_CMD!; !$W_CMD!; !$S_CMD!; !ECHO_CMD!} | |
SET CMD=powershell -command "^& {!CMD!}" ^& ECHO\ ^& "%~dpnx0" timestamp | |
ECHO CMD !CMD! | |
) ELSE ( | |
SET LOOP=FOR /F %%%f IN ^(!CURRENT!^) DO | |
SET OP=del "%%%f" | |
SET CMD=@ECHO OFF ^&^& ^(!LOOP! !OP! ^> nul 2^>^&1 ^) ^& "%~dpnx0" timestamp | |
) | |
rem ECHO !CMD! | |
START "!TITLE! %%t" cmd /k !CMD! | |
) | |
GOTO END | |
:ECHOTIMESTAMP | |
SETLOCAL | |
SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2! | |
SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2! | |
ECHO !DATESTAMP: =0!-!TIMESTAMP: =0! | |
ENDLOCAL | |
GOTO :EOF | |
:END | |
ENDLOCAL | |
EXIT /B |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment