61

The command dir /a displays a list of all the files and folders in a given location.

But it displays the type <JUNCTION> for Junction Points as well as Symbolic Links to Folders. Is there any command which will differentiate and tell me which of these <JUNCTION>'s are Junction Points and which are Symbolic links as well as which of the files are hard links ?

9 Answers 9

27

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

3
  • 1
    "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. Oct 12, 2014 at 6:28
  • 2
    You will have to fire fsutil over each file to detect hardlinks serverfault.com/questions/319134/…
    – Ganesh R.
    Oct 13, 2014 at 16:55
  • 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.
    – Riva
    Jul 23, 2021 at 16:42
82

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

2
  • 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.
    – jaylweb
    Nov 16, 2016 at 16:32
  • 1
    @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.
    – Jimadine
    Apr 28, 2017 at 20:07
28

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.

9
  • 1
    @J.ScottElblein dir 'd:\Temp' -recurse -force | ?{$_.LinkType -eq "Junction"} | select FullName,LinkType,Target Mar 29, 2019 at 10:37
  • 3
    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.
    – NewSites
    Oct 18, 2019 at 16:59
  • 1
    @NewSites are you running poweshell elevated? Oct 18, 2019 at 17:08
  • 1
    Yes, running PS ISE as admin.
    – NewSites
    Oct 18, 2019 at 17:16
  • 1
    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?
    – NewSites
    Oct 18, 2019 at 20:49
4

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.

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"
1
  • It's nice but doesn't work on directories with lots of subfolders.
    – Smeterlink
    Jul 9, 2021 at 3:46
3

There is a trick here. Using Cygwin's Bash shell, it will show you whether some files has hard links.

For example, using mklink /h abc2.log abc1.log to make them mutually hard-linked, you will see hard links count in ls -la output.

enter image description here

3
0

LinkMagic2.exe (Junction list magic) is also good.

I mistakenly deleted all my c:\user Junction links, such as printhood, nethood, and application data when I first installed windows 7 2 years ago because I thought they were put there mistakenly by the install. What they are really for is backwards compatibility, and while searching the internet I see some have gotten in trouble trying to do certain things without these junction points.

0

fsutil:

  1. Junction is possible
  2. SymlinkD is impossible

Powershell:

:uGetTgt2 pathStr selectNum
    if "%~2" equ "" ( set "nPSSub=1" ) else ( set "nPSSub=%~2" )
    set "psCmn=gci '%~1*' -Di | ?{$_.Attributes -match 'ReparsePoint' -and $_.Name -eq '%~n1'} | Select -Exp Target"
    if !nPSSub! equ 1 (
        for /f "delims=" %%p in ('powershell -c "!psCmn!"') do ( set "dirVCVar=%%p" )
    ) else (
        powershell -c "$vr=$(!psCmn!); [Environment]::SetEnvironmentVariable('dirVCVar', $vr, 'Machine')"
    )
exit /b

CMD Script:

:uGetTgt1 pathStr
    set "pathVar=%~1" & call :uGetDir pathVar pathParent pathName
    for /f "tokens=3,* delims=<>[" %%d in ('dir /al "!pathVar!*" 2^>nul ^| findstr /i "<junction> <symlinkd>" 2^>nul') do (
        set "sPname=%%d" & if "!sPname:     %pathName% =!" neq "!sPname!" (
            set "dirVCVar=%%e" & set "dirVCVar=!dirVCVar:~0,-1!" & exit /b
        )
    )
exit /b

this is all of directory only. it is comparing the unique name because of wildcard listing.

1
  • which PowerShell version is it? this code doesn't parse correctly on PS 5.1 Feb 23, 2022 at 11:12
0

If none of these approaches is working for you, it might be that you have a desktop.ini file in the weirdly-named folder which is invoking a LocalizedResourceName feature to change the name in explorer.

Just saying, folks may land here when their problem might be this other one with similar symptoms.

(Who am I kidding? No one's going to be "landing here" as if web search is relevant anymore. I'm just providing training for the next version of ChatGPT ;)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .