Find out whether a file is a symbolic link in PowerShell

后端 未结 7 476
孤城傲影
孤城傲影 2020-12-14 00:19

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

相关标签:
7条回答
  • 2020-12-14 00:55

    Utilize Where-Object to search for the ReparsePoint file attribute.

    Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
    
    0 讨论(0)
  • 2020-12-14 01:00

    The following PowerShell script will list all the files in a directory or directories with the -recurse switch. It will list the name of the file, whether it is a regular file or a hardlinked file, and the size, separated by colons.

    It must be run from the PowerShell command line. It doesn't matter which directory you run it from as that is set in the script.

    It uses the fslink utility shipped with Windows and runs that against each file using the hardlink and list switches and counts the lines of output. If two or greater it is a hardlinked file.

    You can of course change the directory the search starts from by changing the c:\windows\system in the command. Also, the script simply writes the results to a file, c:\hardlinks.txt. You can change the name or simply delete everything from the > character on and it will output to the screen.

    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
    
    0 讨论(0)
  • 2020-12-14 01:03

    Try this:

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

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

    0 讨论(0)
  • 2020-12-14 01:03

    For those that want to check if a resource is a hardlink or symlink:

    (Get-Item ".\some_resource").LinkType -eq "HardLink"
    
    (Get-Item ".\some_resource").LinkType -eq "SymbolicLink"
    
    0 讨论(0)
  • 2020-12-14 01:04

    If you have 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 {D:\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:\.

    0 讨论(0)
  • 2020-12-14 01:06

    here is a one-liner that checks one file $FilePath and returns if it is a symlink or not, works for files and directories

    if((Get-ItemProperty $FilePath).LinkType){"symboliclink"}else{"normal path"}
    
    0 讨论(0)
提交回复
热议问题