I've been learning about NTFS links (1, 2) and playing around with them on my computer. It's a strange world of pseudonyms for filenames and folder names, and I'm not clear yet on why I have them, but what is certain is that I have lots of them.
NTFS links are either hard links or reparse points and reparse points are either junction points or symbolic links.
In order to become more familiar with them, I've been attempting to generate a complete list of all the NTFS links on my computer.
This is a dual-drive computer with the OS on C: and data on D:. The OS is Windows 10 Pro 64 v 1903 (I'm reporting here on results logged before the update to v 1909). PowerShell is the default Windows v 5.1.
In what follows, the terms "directory" and "folder" are synonymous.
All links
PowerShell apparently has, since v 5.0, two undocumented properties of "item" cmdlets: LinkType
and target
(1, 2, 3, 4). LinkType
has the values "Junction", "SymbolicLink", and "HardLink". So this should be able to list all the NTFS links on my computer. However, it does not work reliably. In particular, it fails on certain objects in the "Users" folder. For example, in PowerShell:
PS C:\WINDOWS\system32> echo ("1. " + ("C:\Documents and Settings" | get-item -force).LinkType)
echo ("2. " + ("C:\Program Files\Microsoft Office\root\Client\AppvIsvSubsystems32.dll" | get-item -force).LinkType)
echo ("3. " + ("C:\Program Files\NVIDIA Corporation\NvTelemetry\plugins\NvTelemetry" | get-item -force).LinkType)
echo ("4. " + ("C:\ProgramData\Desktop" | get-item -force).LinkType)
echo ("5. " + ("C:\Users\All Users" | get-item -force).LinkType)
echo ("6. " + ("C:\Users\Default User" | get-item -force).LinkType)
1.
2. SymbolicLink
3. Junction
4.
5.
6.
The corresponding results from dir /aL
in the Windows Command Prompt (see next below) are:
1. JUNCTION
2. SYMLINK
3. JUNCTION
4. JUNCTION
5. SYMLINKD
6. JUNCTION
So it appears that, at least for PowerShell 5.1, LinkType
cannot be trusted.
Reparse points
In the PowerShell cmdlet get-ChildItem
, the parameter attribute
has the property ReparsePoint
. This should allow identifying reparse points, but does not distinguish between junction points and symbolic links, so it is not as useful as dir /aL
, discussed next.
The Windows (Command Prompt, not PowerShell) command dir /aL /s X:\
lists all the reparse points in directory X. Running as administrator, it found none on the data drive and 574 on the system drive, mostly in the folders "Program Files" (not "Program Files (x86)") and "Users", and also a few in "Program Data" and one in "Windows".
In the output of that dir
command, targets are indicated in square brackets after the object names and the column that usually has the file size or "<DIR>
" in it now has five different values: 0 (which is presumably a file size), the usual <DIR>
, and the three new values: <JUNCTION>
, <SYMLINK>
, <SYMLINKD>
. On my computer, on the system drive only, these values occurred with the following frequency and characteristics of the link and target objects:
Count Type/Size Link object Target object
11 <JUNCTION> Folder with root Folder with root
36 Folder not found Folder with root
9 Folder not found Folder w/o root
7 Folder not found Folder not found
10 <SYMLINK> dll file dll file
1 <SYMLINKD> Folder w/o root Folder w/o root
488 <DIR> Folder with root None
12 0 exe file None
----
574 Total
In that table, the object types have the following meanings: (In this item list, dir
means running dir
on the object in the Command Prompt (not PowerShell) as administrator with no parameters (specifically, without the /aL
parameter).)
- Folder with root:
dir
yields a listing that looks like a regular directory listing, starting with<DIR> .
to represent the object (directory) itself.- Example (target object):
dir "C:\Users\Public\Documents"
- Example (target object):
- Folder w/o root:
dir
yields a listing of one or more objects that does not start with either<DIR> .
or the name of the object itself.- Example (target object):
dir "C:\Users\Public\Desktop"
- Example (target object):
- Folder not found:
dir
yields "File not found" and the name of the object does not look like a filename with an extension. (In PowerShell,dir
yields "Access to ... is denied.")- Example (link object):
dir "C:\Documents and Settings"
- Example (link object):
- File:
dir
yields a listing of one item, which is the name of the object itself.- Example (link object):
dir "C:\Program Files\Microsoft Office\root\Office16\C2R64.dll"
- Example (link object):
Obviously, <JUNCTION>
indicates a junction point, while <SYMLINK>
and <SYMLINKD>
indicate symbolic links to files and folders. But I have questions about other information here:
- What are the 500 objects that
dir /aL
says are reparse points, but are marked as<DIR>
or zero file size, and with no targets? Are the<DIR>
objects junction points or symbolic links or something else? Are the zero-size files symbolic links or something else? If they are links, what are they links to? - What are the directory listings that do not start with
<DIR> .
("Folder w/o root")? I've never seen that before. - Why are some junction points and their targets found by
dir
(without/aL
), while others are not?
Hard links
There does not seem to be an easy, native way to get a listing of hard links. Here are six Stack Exchange answers I've found so far on the subject:
- Find out whether a file is a symbolic link in PowerShell.
- Answer by Anton Krouglov has PS command to get links using
LinkType
, which might work for hard links. - Answer by "b_ball" has PS script for hard links using
FSutil
.
- Answer by Anton Krouglov has PS command to get links using
- How to view all the Symbolic links,Junction points,Hard links in a Folder using dir?
- Answer by "Jimadine" has a batch script for getting hard links using
FSutil
, but I didn't succeed in getting it to work. - Answer by Anton Krouglov repeats stuff about
LinkType
from his answer to the other question above.
- Answer by "Jimadine" has a batch script for getting hard links using
- How do I view a file's hard links in Windows?
- Answers by "antonio" and "Massimo" suggest SysInternals'
FindLinks
.
- Answers by "antonio" and "Massimo" suggest SysInternals'
I have not finished testing all the methods. Any suggestions for pursuing this line of inquiry effectively to get a correct list of all hard links?
Summary
- Re all links: Any comment on my finding that
LinkType
cannot be trusted to report all NTFS links correctly? - Re reparse point: Any answers to the three questions stated at the end of that section?
- Re hard links: Any suggestion for getting a good listing?
- Any other wisdom or insights to share about this strange world of file system pseudonyms?