How to view all the Symbolic links,Junction points,Hard links in a Folder using dir?

The command dir /a displays a list of all the files,folders in a given location. But it displays the type for Junction Points as well as Symbolic Links to Folders. Is there any command which will differentiate and tell me which of these are Junction Points and which are Symbolic links as well as which of the files are hard links ?


Solution 1:

Why not use junction.exe from SysInternals? It allows you to list all junctions in a particular folder or its sub folders.

From the website:

Introduction

Windows 2000 and higher supports directory symbolic links, where a directory serves as a symbolic link to another directory on the computer. For example, if the directory D:\SYMLINK specified C:\WINNT\SYSTEM32 as its target, then an application accessing D:\SYMLINK\DRIVERS would in reality be accessing C:\WINNT\SYSTEM32\DRIVERS. Directory symbolic links are known as NTFS junctions in Windows. Unfortunately, Windows comes with no tools for creating junctions—you have to purchase the Win2K Resource Kit, which comes with the linkd program for creating junctions. I therefore decided to write my own junction-creating tool: Junction. Junction not only allows you to create NTFS junctions, it allows you to see if files or directories are actually reparse points. Reparse points are the mechanism on which NTFS junctions are based, and they are used by Windows' Remote Storage Service (RSS), as well as volume mount points.

Please read this Microsoft KB article for tips on using junctions.

Notethat Windows does not support junctions to directories on remote shares.

If you want to view reparse information, the usage for Junction is the following:

Using Junction

Use junction to list junctions:

Usage: [-s]

-s Recurse subdirectories

Examples:

To determine if a file is a junction, specify the file name:

junction c:\test

To list junctions beneath a directory, include the –s switch:

junction -s c:\

To create a junction c:\Program-Files for "c:\Program Files":

C:>md Program-Files

C:>junction c:\Program-Files "c:\Program Files"

To delete a junction, use the –d switch:

junction -d c:\Program-Files

Solution 2:

You don't necessarily need to download additional programs to list junctions, symlinks and hard links, but if you have specific output format requirements, they may help.

List all junctions, symlinks and symlink directories in the current directory and its subdirectories:

dir /al /s

Or if you want them listed separately...

List all junctions in the current directory and its subdirectories:

dir /al /s | findstr "<JUNCTION>"

List all symlinks in the current directory and its subdirectories:

dir /al /s | findstr "<SYMLINK>"

List all symlink directories in the current directory and its subdirectories:

dir /al /s | findstr "<SYMLINKD>"

The l attribute flag is key here; l is for Reparse Points (junctions, symlinks and symlink directories)

Hard links

Unfortunately dir lists hard links as normal files, so you cannot use it to identify hard links. You an use the inbuilt fsutil instead. It needs to be run from an elevated command prompt.

With fsutil, list all hard links in the current directory and its subdirectories:

for /F "usebackq tokens=2* delims=:" %G in (`forfiles /s /c "cmd /c fsutil hardlink list @path | findstr /n .* | findstr /b /v 1"`) do @fsutil hardlink list "%G" & echo.

This one-liner is not ideal, and I would welcome any improvements.

  • Using forfiles with the recurse subdirectories option (/s) hammered my CPU, and took a while to complete.
  • The fsutil basically ends up running twice; the first time to identify the hard links by counting the number of output lines returned by each call, and the second time on just-found hard links to get the output right.
  • There will be duplicate lines. To eliminate them you'd want to redirect the output to a file and then run the file through a tool like uniq.

Here's a batch file that uses just for to identify hard links. As forfiles is not involved, it may be slightly faster, however it still suffers the remaining caveats of the above one-liner.

@echo off
AT > NUL
if %ERRORLEVEL% NEQ 0 echo You need to run this script from an elevated command prompt. Exiting. && exit /B 1

for /R "%CD%" %%a IN (*.*) do (
 for /F "usebackq tokens=2* delims=:" %%b in (`fsutil hardlink list "%%a" ^| findstr /n .* ^| findstr /b /v 1`) do (
    fsutil hardlink list "%%b"
    REM The following echo command breaks up each group of hard links with a blank line
    echo.       
  )
)

There are a few other (untested) options:

Use the (old) Microsoft HL Scan utility

hlscan /dir %CD%

Use the alternative find command that comes with the Microsoft's SFUA utility toolkit:

find . -links +1

Use the Sysinternals' findlinks utility in a similar way to fsutil mentioned above

Use Uwe Sieber's ListLinks program - see link for usage

Use Nirsoft's NTFSLinksView if you prefer a GUI application

Solution 3:

As of Powershell 5+ the following one-liner recursively lists all file hardlinks, directory junctions and symbolic links and their targets starting from d:\Temp\:

dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,Target

Output:

FullName                                LinkType     Target
--------                                --------     ------
D:\Temp\MyJunctionDir                   Junction     {D:\exp\junction_target_dir}
D:\Temp\MySymLinkDir                    SymbolicLink {D:\exp\symlink_target_dir}
D:\Temp\MyHardLinkFile.txt              HardLink     {D:\temp\MyHardLinkFile2.txt, D:\exp\hlink_target.xml}
D:\Temp\MyHardLinkFile2.txt             HardLink     {D:\temp\MyHardLinkFile.txt, D:\exp\hlink_target.xml}
D:\Temp\MySymLinkFile.txt               SymbolicLink {..\exp\symlink_target.xml}
D:\Temp\MySymLinkDir\MySymLinkFile2.txt SymbolicLink {D:\temp\normal file.txt}

If you care about multiple targets for hardlinks use this variation which lists targets tab-separated:

dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,@{ Name="Targets"; Expression={$_.Target -join "`t"} }

You may need administrator privileges to run this script on say C:\.

To run these scripts from traditional command line (cmd.exe):

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "<PowerShell commands>"

For instance:

C:\>PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "dir 'd:\Temp' -recurse -force | ?{ $_.LinkType } | select FullName, LinkType, @{ Name = \"Targets\"; Expression = { $_.Target -join \"`t\" } }"

Solution 4:

Hard links are better described as above, but for Symbolic Links and Junctions the following works nicely:

I'm not using any new commands here, however it improves upon some listed by showing you a nice list of each link found, in the path, it's type (SymLink/Junction) and both the Link path and the target path.

There are some good ones above but they only give you the TARGET path, and usually you want to delete the link, and not the target, or correlate all links and targets.

To get the Type, Link, and Target, you can use the following in CMD:

FOR /F "Tokens=*" %A IN ('DIR /al /b /s G:\') DO @( for /F "Tokens=2,4 delims=<[]>" %B IN ('DIR /al "%~A"? ^| FIND /I " %~nA " ^| FIND /I "<" ^| FIND /I ">" ') DO @( ECHO.%~B: "%~A" → "%~C" ) )

Example output:

SYMLINK: "G:\FTP\Root" → "G:\FTP\Data"
JUNCTION: "G:\FTP\Junctioned\BT\02" → "W:\FTPRoot\02"

Solution 5:

Far Manager 3.0 can both search for and display symlinks and junction points as different from files and directories. (It can do so many other things.) It can also search for hard links.

ALT+F7 => [x] Use filter => Filter => Ins

Choose the attributes you want.