How to safely recursively delete a directory in Windows?
Solution 1:
For deleting all files which are not a junction, this command should do it:
del /s /a:-l
Where:
-
/s
: recurse -
/a:-l
: only files which are not reparse points
NTFS reparse points include Directory junctions, Symbolic links and Volume mount points.
A small test of what will be deleted can be done using the command:
dir /s /a:-l
(I would still take a backup of the folder if it's important.)
Solution 2:
rmdir will delete the symbolic link.
del will delete the links destination but not the link.
rmdir /S /Q
will delete the directory recursively and won't follow symlinks.
I have tested and confirmed the behaviour with cmd in Windows 10:
#create directory structure
C:\Users\username\test>mkdir 1 2 3
C:\Users\username\test>mkdir 1\testdir
C:\Users\username\test>mkdir 1\testdir\1
#create symbolic link to directory
C:\Users\username\test>mklink /D testlink 1\testdir\1
symbolische Verknüpfung erstellt für testlink <<===>> 1\testdir\1
C:\Users\username\test>dir
Verzeichnis von C:\Users\username\test
28.12.2021 20:24 <DIR> .
28.12.2021 20:24 <DIR> ..
28.12.2021 20:23 <DIR> 1
28.12.2021 20:23 <DIR> 2
28.12.2021 20:23 <DIR> 3
28.12.2021 20:24 <SYMLINKD> testlink [1\testdir\1]
0 Datei(en), 0 Bytes
6 Verzeichnis(se), 22.185.267.200 Bytes frei
#test rmdir with the named parameters
C:\Users\username\test>rmdir /s /q testlink
C:\Users\username\test>dir
Verzeichnis von C:\Users\username\test
28.12.2021 20:25 <DIR> .
28.12.2021 20:25 <DIR> ..
28.12.2021 20:23 <DIR> 1
28.12.2021 20:23 <DIR> 2
28.12.2021 20:23 <DIR> 3
0 Datei(en), 0 Bytes
5 Verzeichnis(se), 22.185.267.200 Bytes frei
C:\Users\username\test>cd 1\testdir\
#obviously the subdirectory in the linked-to directory is still there
C:\Users\username\test\1\testdir>dir
Verzeichnis von C:\Users\username\test\1\testdir
28.12.2021 20:23 <DIR> .
28.12.2021 20:23 <DIR> ..
28.12.2021 20:24 <DIR> 1
0 Datei(en), 0 Bytes
3 Verzeichnis(se), 22.184.206.336 Bytes frei
According to this comment rmdir will behave different if invoked from powershell than from cmd, I have however not tested it with powershell.