Подтвердить что ты не робот

Узнайте, является ли файл символической ссылкой в ​​PowerShell

У меня есть PowerShell script, который идет по дереву каталогов, и иногда у меня есть файлы с жесткими ссылками, которые не должны обрабатываться. Есть ли простой способ выяснить, является ли файл (т.е. System.IO.FileInfo) жесткой ссылкой или нет?

Если нет, было бы проще с символическими ссылками (символическими ссылками)?

4b9b3361

Ответ 1

Попробуйте следующее:

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

Это довольно минимальная реализация, но она должна сделать трюк. Обратите внимание, что это не различает жесткую ссылку и символическую ссылку. Внизу они оба просто используют точки повторной обработки NTFS, IIRC.

Ответ 2

Используйте Where-Object для поиска атрибута файла ReparsePoint.

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

Ответ 3

Если у вас есть 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"} }

Вам могут потребоваться права администратора для запуска этого script, например C:\.

Ответ 4

Мои результаты в Vista, используя Keith Hill powershell script для тестирования символических ссылок и жестких ссылок:

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, а hardlinks - нет.

Ответ 5

В следующем PowerShell script будут перечислены все файлы в каталоге или каталогах с помощью переключателя -recurse. Он будет отображать имя файла, будь то обычный файл или файл с жесткой привязкой, и размер, разделенный двоеточиями.

Он должен запускаться из командной строки PowerShell. Неважно, какой каталог вы запускаете из него, как это установлено в script.

Он использует утилиту fslink, поставляемую с Windows, и запускает ее по каждому файлу с помощью переключателей hardlink и list и подсчитывает линии вывода. Если два или больше, это файл с жесткой привязкой.

Вы можете, конечно, изменить каталог, с которого начинается поиск, изменив c:\windows\system в команде. Кроме того, script просто записывает результаты в файл, c:\hardlinks.txt. Вы можете изменить имя или просто удалить все из символa > , и он будет выводиться на экран.

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