Узнайте, является ли файл символической ссылкой в PowerShell
У меня есть сценарий PowerShell, который идет по дереву каталогов, и иногда у меня есть вспомогательные файлы, жестко связанные там, которые не должны обрабатываться. Есть ли простой способ узнать, является ли файл (то есть,System.IO.FileInfo
) - Это жесткая ссылка или нет?
если нет, было бы проще с символическими ссылками (символическими ссылками)?
5 ответов
попробуйте это:
function Test-ReparsePoint([string]$path) {
$file = Get-Item $path -Force -ea SilentlyContinue
return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint)
}
Это довольно минимальная реализация, но она должна сделать трюк. Обратите внимание, что это не отличает жесткую ссылку от символической ссылки. Под, они оба просто воспользоваться точки повторного разбора NTFS, IIRC.
использовать Where-Object
для поиска атрибута файла ReparsePoint.
Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
если у вас есть 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"} }
вам могут потребоваться права администратора для запуска этого сценария на say C:\
.
мои результаты в Vista, используя сценарий powershell кита Хилла для тестирования символических и жестких ссылок:
c:\markus\other>mklink symlink.doc \temp06rsltns.doc
symbolic link created for symlink.doc <<===>> \temp06rsltns.doc
c:\markus\other>fsutil hardlink create HARDLINK.doc \temp06rsltns.doc
Hardlink created for c:\markus\other\HARDLINK.doc <<===>> c:\temp06rsltns.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 [\temp06rsltns.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, а жесткие ссылки-нет.
следующий сценарий PowerShell перечислит все файлы в каталоге или каталогах с параметром-recurse. Он будет перечислять имя файла, будь то обычный файл или файл с жесткой связью, и размер, разделенный двоеточиями.
его необходимо запустить из командной строки PowerShell. Не имеет значения, из какого каталога вы его запускаете, поскольку это задано в скрипте.
он использует утилиту fslink, поставляемую с Windows, и запускает ее для каждого файла с помощью hardlink и список переключает и подсчитывает линии вывода. Если два или больше, это жестко связанный файл.
вы можете, конечно, изменить каталог, из которого начинается поиск, изменив 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