views:

437

answers:

2

Edit: Changed the question title since the answer explicitly only handles Symlinks.

I am having a Powershell script which is walking a directory tree and sometimes I have auxiliary files hardlinked there which should not be processed. Is there an easy way of finding out whether a file (i. e. System.IO.FileInfo) is a hard link or not?

If not, would it be easier with symlinks?

+5  A: 

Try this:

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

It is a pretty minimal impl but should do the trick. Note that this doesn't distinguish between a hard link and a symlink. Underneath, they both just take advantage of NTFS reparse points IIRC.

Keith Hill
Hard links are simply additional file entries in the MFT and as such appear as normal files, unless somebody looks at the number of links to that file. But I didn't try out a symlink so far. Indeed it has the ReparsePoint attribute set. Thanks. (Even though symlinks are more cumbersome to handle, since I don't have permissions to create them by default :/)
Joey
I think it's not true that hardlinks and symlinks use the same mechanism. As Johannes pointed out, hardlinks are just another entry in the MFT. A symlink is a Reparse point. They're different. http://stackoverflow.com/questions/817794/find-out-whether-a-file-is-a-symlink-in-powershell/2255548#2255548
Cheeso
A: 

My results on Vista, using Keith Hill's powershell script to test symlinks and hardlinks:

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

It shows that symlinks are reparse points, and have the ReparsePoint FileAttribute bit set, while hardlinks do not.

Cheeso