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

106,539

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\" } }"

Update Feb 2022: For the newer Windows versions you should use Powershell v7.1 or later. It is somewhat stripped down when comparing to v5.1, but in this particular case it shows correct LinkType.

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.

Share:
106,539
Dhiwakar Ravikumar
Author by

Dhiwakar Ravikumar

QA Automation Engineer with over 7 years of experience. I worked on delivering several features and products to customers with a high degree of quality. I have designed automation frameworks from scratch &amp; automated several test cases to help boost productivity and increase test coverage while simultaneously improving QA standards. I used to work at Commvault and now I work at Cohesity.

Updated on September 18, 2022

Comments

  • Dhiwakar Ravikumar
    Dhiwakar Ravikumar almost 2 years

    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 ?

  • Dhiwakar Ravikumar
    Dhiwakar Ravikumar over 9 years
    "junction" can identify Symbolic Links and Junction Points. Thanks. It does not identify hard links. What command will give me a list of all the files/filenames that hard links. Alternatively is there any way of getting the link count of a file ? I know that link count of a file corresponds to how many hard links it has.
  • John
    John over 9 years
    You will have to fire fsutil over each file to detect hardlinks serverfault.com/questions/319134/…
  • jaylweb
    jaylweb over 7 years
    In Windows 7, dir /al /s does not show a symlink directory The OP tagged Windows 7, therefore this does not answer the OPs question.
  • Jimadine
    Jimadine about 7 years
    @jaylweb (1) dir /al /s lists all reparse points. See further down my answer for listing symlink directories only. (2) You're wrong, this does answer the question.
  • J. Scott Elblein
    J. Scott Elblein over 5 years
    How do you alter this to just show Junctions? I'm not real familiar with PowerShell commands.
  • Anton Krouglov
    Anton Krouglov over 5 years
    @J.ScottElblein dir 'd:\Temp' -recurse -force | ?{$_.LinkType -eq "Junction"} | select FullName,LinkType,Target
  • NewSites
    NewSites over 4 years
    LinkType does not appear to be reliable for reparse points. For example, on my computer running W10 with PS 5.1, LinkType is null for both "C:\ProgramData\Desktop" and "C:\Users\All Users", whereas dir /aL (Command Prompt, not PowerShell) indicates the first is a junction point and the second a symbolic link.
  • Anton Krouglov
    Anton Krouglov over 4 years
    @NewSites are you running poweshell elevated?
  • NewSites
    NewSites over 4 years
    Yes, running PS ISE as admin.
  • NewSites
    NewSites over 4 years
    Are you able to test "C:\ProgramData\Desktop" and "C:\Users\All Users", as well as "C:\Documents and Settings" (also has null LinkType but dir /aL says it's a junction point) in W10 with PS 5.1? Do you get a non-null value for LinkType on them?
  • not2qubit
    not2qubit over 3 years
    Lovely prompt you got there! How is it coded?
  • Jimm Chen
    Jimm Chen over 3 years
    @not2qubit For beautiful(and rather complex) PS1, check final 8 lines of this file: github.com/chjfth/dailytools/blob/master/bash-qlbox/…
  • not2qubit
    not2qubit over 3 years
    Thanks! Lot's of useful stuff in there.
  • Smeterlink
    Smeterlink almost 3 years
    It's nice but doesn't work on directories with lots of subfolders.
  • Riva
    Riva almost 3 years
    Be careful with SysInternals junction tool ! It does not support non-ASCII characters in file / directory names. Listing junctions with UTF characters in names will give you mangled letters. Creating junctions with UTF characters will result in junctions created with mangled letters.
  • AutoMattTick
    AutoMattTick over 2 years
    Same here. In c:\users both get-childitem -force and get-item -force are returning null in the linktype for both "All Users" and "Default Users". (Cmd's dir /aL reports it correctly.) Tested on both Server 2016 PSVersion 5.1.14393.4583, and Windows 10 PSVersion 5.1.19041.1237
  • quetzalcoatl
    quetzalcoatl over 2 years
    Same here. Elevated. Windows 10 Pro, 21H2, 19044.1526, PS 5.1 5.1.19041.1320, lots of links have LinkType null.
  • quetzalcoatl
    quetzalcoatl over 2 years
    which PowerShell version is it? this code doesn't parse correctly on PS 5.1
  • Anton Krouglov
    Anton Krouglov over 2 years
    @quetzalcoatl try powershell 7.1. It worked for me on Win 10 1809.