2009-05-03 53 views
17

我有一个PowerShell脚本正在步行目录树,有时候我有那些不应该被处理的硬链接的辅助文件。是否有一种简单的方法来查明文件(即,System.IO.FileInfo)是否是一个硬链接?找出一个文件是否是PowerShell中的符号链接

如果没有,符号链接(符号链接)会更容易吗?

回答

30

试试这个:

function Test-ReparsePoint([string]$path) { 
    $file = Get-Item $path -Force -ea SilentlyContinue 
    return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint) 
} 

这是一个非常最小的实现,但它应该做的伎俩。请注意,这不区分硬链接和符号链接。在下面,他们都利用了NTFS reparse points,IIRC

+0

硬链接仅仅是MFT中的附加文件条目,因此除非有人查看指向该文件的链接数,否则将显示为普通文件。但到目前为止我没有尝试一个符号链接。确实它有ReparsePoint属性集。谢谢。(即使符号链接处理起来比较麻烦,因为我没有默认创建它们的权限:/) – Joey 2009-05-03 21:46:25

+2

我认为硬链接和符号链接使用相同的机制是不正确的。正如约翰内斯指出的那样,硬连接只是MFT中的另一个入口。符号链接是重新分析点。他们不同。 http://stackoverflow.com/questions/817794/find-out-whether-a-file-is-a-symlink-in-powershell/2255548#2255548 – Cheeso 2010-02-12 22:23:19

3

我的成绩在Vista上使用基思·希尔的PowerShell脚本,以测试符号链接和硬链接:

c:\markus\other>mklink symlink.doc \temp\2006rsltns.doc 
symbolic link created for symlink.doc <<===>> \temp\2006rsltns.doc 

c:\markus\other>fsutil hardlink create HARDLINK.doc \temp\2006rsltns.doc 
Hardlink created for c:\markus\other\HARDLINK.doc <<===>> c:\temp\2006rsltns.doc 

c:\markus\other>dir 
Volume in drive C has no label. 
Volume Serial Number is C8BC-2EBD 

Directory of c:\markus\other 

02/12/2010 05:21 PM <DIR>   . 
02/12/2010 05:21 PM <DIR>   .. 
01/10/2006 06:12 PM   25,088 HARDLINK.doc 
02/12/2010 05:21 PM <SYMLINK>  symlink.doc [\temp\2006rsltns.doc] 
       2 File(s)   25,088 bytes 
       2 Dir(s) 6,805,803,008 bytes free 

c:\markus\other>powershell \script\IsSymLink.ps1 HARDLINK.doc 
False 

c:\\markus\other>powershell \script\IsSymLink.ps1 symlink.doc 
True 

这表明符号链接是重分析点,并有ReparsePoint FileAttribute位设置,而硬链接没有。

2

以下PowerShell脚本将使用-recurse开关列出一个或多个目录中的所有文件。它将列出文件的名称,无论是普通文件还是硬链接文件,以及用冒号分隔的大小。

它必须从PowerShell命令行运行。无论您在哪个目录中运行它,都是在脚本中设置的。

它使用Windows附带的fslink实用程序,并使用硬链接和列表开关对每个文件运行该命令,并对输出行进行计数。如果两个或更多,它是一个硬链接文件。

您当然可以通过在命令中更改c:\windows\system来更改搜索开始的目录。此外,该脚本只是将结果写入文件c:\hardlinks.txt。您可以更改名称或直接从>字符中删除所有内容,并将其输出到屏幕上。

Get-ChildItem -path C:\Windows\system -file -recurse -force | 
    foreach-object { 
     if ((fsutil hardlink list $_.fullname).count -ge 2) { 
      $_.PSChildname + ":Hardlinked:" + $_.Length 
     } else { 
      $_.PSChildname + ":RegularFile:" + $_.Length 
     } 
    } > c:\hardlinks.txt 
10

利用Where-Object来搜索ReparsePoint文件属性。

Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" } 
6

如果您有PowerShell的5+下面的一行递归地列出了所有的文件的硬链接,目录连接和符号链接,并从d:\Temp\开始他们的目标:

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

输出:

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 {D:\exp\symlink_target.xml} 
D:\Temp\MySymLinkDir\MySymLinkFile2.txt SymbolicLink {D:\temp\normal file.txt} 

如果您关心硬链接的多个目标,请使用此变体列出以制表符分隔的目标:

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

您可能需要管理员权限才能在C:\上运行此脚本。

相关问题