Узнайте, является ли файл символической ссылкой в ​​PowerShell - PullRequest
23 голосов
/ 03 мая 2009

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

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

Ответы [ 5 ]

32 голосов
/ 04 мая 2009

Попробуйте это:

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

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

16 голосов
/ 08 февраля 2017

Если у вас 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:\.

14 голосов
/ 30 декабря 2015

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

Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
3 голосов
/ 13 февраля 2010

Мои результаты в 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 голосов
/ 13 июня 2015

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

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

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

Конечно, вы можете изменить каталог, с которого начинается поиск, изменив 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
...