我一直在学习 NTFS 链接(1、2)并在我的电脑上玩弄它们。这是一个奇怪的文件名和文件夹名称的假名世界,我还不清楚为什么我有它们,但可以肯定的是我有很多。
NTFS 链接要么是硬链接,要么是重解析点,重解析点要么是连接点,要么是符号链接。
为了更加熟悉它们,我一直在尝试生成我计算机上所有 NTFS 链接的完整列表。
这是一台双驱动器计算机,操作系统在 C: 上,数据在 D: 上。操作系统是 Windows 10 Pro 64 v 1903(我在这里报告更新到 v 1909 之前记录的结果)。PowerShell 是默认的 Windows v 5.1。
在下文中,术语“目录”和“文件夹”是同义词。
所有链接
从 v 5.0 开始,PowerShell 显然有两个“item” cmdlet 的未记录属性:LinkType
和target
( 1 , 2 , 3 , 4 )。LinkType
具有值“Junction”、“SymbolicLink”和“HardLink”。所以这应该能够列出我电脑上的所有 NTFS 链接。但是,它不能可靠地工作。特别是,它在“用户”文件夹中的某些对象上失败。例如,在 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.
dir /aL
Windows 命令提示符(见下文)中的相应结果是:
1. JUNCTION
2. SYMLINK
3. JUNCTION
4. JUNCTION
5. SYMLINKD
6. JUNCTION
因此,至少对于 PowerShell 5.1,似乎LinkType
是不可信的。
重解析点
在 PowerShell cmdletget-ChildItem
中,参数attribute
具有属性ReparsePoint
。这应该允许识别重解析点,但不区分连接点和符号链接,因此它不如dir /aL
下面讨论的有用。
Windows(命令提示符,不是 PowerShell)命令dir /aL /s X:\
列出了目录 X 中的所有重解析点。以管理员身份运行,它在数据驱动器上没有找到,在系统驱动器上找到 574,主要在文件夹“程序文件”(不是“程序文件” (x86)") 和“用户”,还有一些在“程序数据”中,一个在“Windows”中。
在该dir
命令的输出中,目标在对象名称之后的方括号中指示,并且通常具有文件大小或“ <DIR>
”的列现在具有五个不同的值:0(可能是文件大小),通常的<DIR>
,和三个新值:<JUNCTION>
, <SYMLINK>
, <SYMLINKD>
. 在我的计算机上,仅在系统驱动器上,这些值以以下链接和目标对象的频率和特征出现:
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
在该表中,对象类型具有以下含义:(在此项目列表中,表示在命令提示符(不是 PowerShell)中以管理员身份在对象上dir
运行,不带参数(特别是不带参数)。)dir
/aL
- 带有根的文件夹:
dir
产生一个看起来像常规目录列表的列表,<DIR> .
以表示对象(目录)本身开始。- 示例(目标对象):
dir "C:\Users\Public\Documents"
- 示例(目标对象):
- 无根文件夹:
dir
生成一个或多个对象的列表,这些对象不<DIR> .
以对象本身的名称或名称开头。- 示例(目标对象):
dir "C:\Users\Public\Desktop"
- 示例(目标对象):
- 找不到文件夹:
dir
产生“找不到文件”并且对象的名称看起来不像带扩展名的文件名。(在 PowerShell 中,dir
产生“访问...被拒绝。”)- 示例(链接对象):
dir "C:\Documents and Settings"
- 示例(链接对象):
- 文件:
dir
产生一个项目的列表,即对象本身的名称。- 示例(链接对象):
dir "C:\Program Files\Microsoft Office\root\Office16\C2R64.dll"
- 示例(链接对象):
显然,<JUNCTION>
表示连接点,而<SYMLINK>
和<SYMLINKD>
表示文件和文件夹的符号链接。但我对这里的其他信息有疑问:
- 什么是 500 个对象,
dir /aL
说是重解析点,但被标记为<DIR>
文件大小或文件大小为零,并且没有目标?对象是<DIR>
连接点还是符号链接或其他东西?零大小文件是符号链接还是其他?如果它们是链接,它们链接到什么? - 不以
<DIR> .
(“无根文件夹”)开头的目录列表是什么?我以前从未见过。 - 为什么有些连接点及其目标可以通过
dir
(不带/aL
)找到,而有些则没有?
硬链接
似乎没有一种简单的本地方式来获取硬链接列表。以下是我迄今为止在该主题上找到的六个 Stack Exchange 答案:
- 找出文件是否是 PowerShell 中的符号链接。
- Anton Krouglov 的回答有 PS 命令来使用 获取链接
LinkType
,这可能适用于硬链接。 - “b_ball”的回答有用于硬链接的 PS 脚本,使用
FSutil
.
- Anton Krouglov 的回答有 PS 命令来使用 获取链接
- 如何使用目录查看文件夹中的所有符号链接、连接点、硬链接?
- “Jimadine”的回答有一个使用 获取硬链接的批处理脚本
FSutil
,但我没有成功让它工作。 - Anton Krouglov 的回答重复了
LinkType
他对上述另一个问题的回答。
- “Jimadine”的回答有一个使用 获取硬链接的批处理脚本
- 如何在 Windows 中查看文件的硬链接?
- “antonio”和“Massimo”的回答建议使用 SysInternals'
FindLinks
。
- “antonio”和“Massimo”的回答建议使用 SysInternals'
我还没有完成所有方法的测试。有什么建议可以有效地进行这一调查以获取所有硬链接的正确列表?
概括
- 重新链接所有链接:对我的发现有任何评论
LinkType
不能正确报告所有 NTFS 链接吗? - 重新解析点:对该部分末尾所述的三个问题有任何答案吗?
- 重新硬链接:对获得好的列表有什么建议吗?
- 关于这个奇怪的文件系统假名世界,还有什么其他的智慧或见解可以分享吗?
我怀疑硬链接一旦创建就会显示为不同的 LinkType,因为它们的工作方式是让多个名称(目录条目)像原始名称一样指向同一个文件对象。
确定文件是否有的唯一方法硬链接的唯一方法是检查其“链接计数”,如
fsutil
您找到的脚本中所示。同样,在 Linux 上,POSIX stat() 具有 'nlink' 属性,告诉您文件具有的链接数(这是显示在 中的数字ls -l
)。然而,在 NTFS 中几乎没有——在大多数 Unix 文件系统中也没有——可以让你区分硬链接和原始文件。您只能说两个文件是硬链接的,因为它们指向同一个“inode”(嗯,NTFS 等价物),但您不会知道后来添加了哪个链接:它只是一个有两个名称的文件。
并非所有重解析点都是链接。它们可以有各种标签,它们的一般目的只是将文件查找重定向到某个驱动程序。
例如,Windows 允许将驱动器/卷安装在空文件夹(Unix 风格)上,而不是给它们一个“驱动器号”。然而,与临时的 Unix 挂载点不同,Windows 挂载点在文件系统中是持久的——它们是一种存储已挂载卷 ID 的重解析点。
重解析点的另一个非常常见的用途是实现“云”或“仅在线”文件,如在 OneDrive 和 Dropbox 中(两者的实现方式也非常不同)——它们显示为常规文件,一旦打开就会触发在线下载.
如果您使用以某种方式安装的 Microsoft Office(不完全确定,但我认为它是通过 ClickOnce 安装的 Office 365),它似乎使用了另一种类型的重解析点,它们既不是连接也不是符号链接。用来
fsutil reparsepoint query
看看你是否能找到任何有趣的东西。不幸的是,“找不到文件”也是 CMD 报告由于安全限制引起的错误的方式——这并不意味着它成功地检索了一个空列表。
“文档和设置”是一个标准的连接点,它只有一个 ACL(请参阅
icacls
参考资料),它明确拒绝列出其内容。有一篇旧的 blogs.msdn.com 帖子说这样做是为了避免某些链接无知程序扫描相同的用户配置文件目录两次。