Узнайте, является ли файл символической ссылкой в PowerShell
У меня есть PowerShell script, который идет по дереву каталогов, и иногда у меня есть файлы с жесткими ссылками, которые не должны обрабатываться. Есть ли простой способ выяснить, является ли файл (т.е. System.IO.FileInfo
) жесткой ссылкой или нет?
Если нет, было бы проще с символическими ссылками (символическими ссылками)?
Ответы
Ответ 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