batch file (windows cmd.exe) test if a directory is a link (symlink)

You have three methods

Solution 1: fsutil reparsepoint

Use symlink/junction with fsutil reparsepoint query and check %errorlevel% for success, like this:

set tmpfile=%TEMP%\%RANDOM%.tmp

fsutil reparsepoint query "%DIR%" >"%tmpfile%"
if %errorlevel% == 0 echo This is a symlink/junction
if %errorlevel% == 1 echo This is a directory

This works, because fsutil reparsepoint query can't do anything on a standard directory and throws an error. But the permission error causes %errorlevel%=1 too!

Solution 2: dir + find

List links of the parent directory with dir, filter the output with find and check %errorlevel% for success, like this:

set tmpfile=%TEMP%\%RANDOM%.tmp

dir /AL /B "%PARENT_DIR%" | find "%NAME%" >"%tmpfile%"
if %errorlevel% == 0 echo This is a symlink/junction
if %errorlevel% == 1 echo This is a directory

Solution 3: for (the best)

Get attributes of the directory with for and check the last from it, because this indicates links. I think this is smarter and the best solution.

for %i in ("%DIR%") do set attribs=%~ai
if "%attribs:~-1%" == "l" echo This is a symlink/junction

FYI: This solution is not dependent on %errorlevel%, so you can check "valid errors" too!

Sources

  • http://blogs.technet.com/b/filecab/archive/2013/02/14/dfsr-reparse-point-support-or-avoiding-schr-246-dinger-s-file.aspx
  • How to get attributes of a file using batch file

general code:

fsutil reparsepoint query "folder name" | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

figure out, if the current folder is a symlink:

fsutil reparsepoint query "." | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

figure out, if the parent folder is a symlink:

fsutil reparsepoint query ".." | find "Symbolic Link" >nul && echo symbolic link found || echo No symbolic link

Update: this solved my problem, but as commenters noted, dir will show both directory symlinks and directory junctions. So it's wrong answer if junctions are there.


Simple dir /A:ld works fine

dir /?:

DIR [drive:][path][filename] [/A[[:]attributes]] …

/A          Displays files with specified attributes.  
attributes   D  Directories                R  Read-only files  
             H  Hidden files               A  Files ready for archiving  
             S  System files               I  Not content indexed files  
             L  Reparse Points             -  Prefix meaning not  

Note that to execute a command only for non-link folders, you can use the attribute negation form:

for /F "usebackq" %%D in (`dir /A:D-L /B some-folder`) do (
    some-command some-folder\%%D
)