Как я могу проверить в коде PowerShell, является ли папка точкой соединения?
Проверить в коде PowerShell, является ли папка точкой соединения?
Ответы (6)
Взгляните на этот блог: https://web.archive.org/web/20190422210654/https://devblogs.microsoft.com/powershell/viewing-junctions-with-dir/
способ сделать это — скопировать встроенный файл форматирования файловой системы, изменить его так, чтобы были указаны соединения, а затем загрузить его с помощью Update-FormatData:
Из блога:
Правила форматирования файловой системы находятся в
$pshome\FileSystem.Format.ps1xml
. Я скопировал это, затем в элементе[ViewDefinitions –> View –> TableControl –> TableRowEntries –> TableRowEntry –> TableColumnItems –> TableColumnItem]
я изменил содержимое PropertyName со значением Mode на следующее:<ScriptBlock> "$($_.Mode)$(if($_.Attributes -band [IO.FileAttributes]::ReparsePoint) {'J'})" </ScriptBlock>
Это выполняет побитовое И для свойства атрибутов объекта DirectoryInfo (
$_.Attributes
) по отношению к значению перечисления .NetSystem.IO.FileAttributes.ReparsePoint
. Если результат не равен нулю, он отображает «J» рядом с другими атрибутами режима файла. Затем загрузите новый файл форматирования следующим образом:PS> Update-FormatData -PrependPath myFilesystem.format.ps1xml
Параметр PrependPath обеспечивает загрузку нового файла форматирования перед встроенными файлами форматирования.
Ссылка на каталог имеет «J» в столбце режима, похоже, работает!
Он находится в столбце режима J для перекрестка.
If (Get-Item Проверить папку).Attributes.ToString().Contains("ReparsePoint"){Код}
По крайней мере, начиная с PowerShell v5.0, есть лучшая поддержка ссылок (или, как их называет MS: Reparse Points)
улучшенный элемент командлеты — свойство LinkType
Связанная статья находится в категории WMF 5.0, что может означать, что этот метод был доступен, начиная с версии PS 5.0.
Эти функции были включены в стандартные команды Get-Item, Get-ChildItem, поэтому дополнительные действия не требуются. Его можно использовать на любой текущей PS.
LinkType — это строковое свойство объекта, возвращаемое Get-Item и Get-ChildItem.
оно может иметь одно из следующих четырех значений: '', 'Junction', 'SymbolicLink', 'HardLink'.
Чтобы ответить на вопрос ОП, вы можете проверить, является ли папка точкой соединения, используя:
if ((Get-Item -Path $Target -Force).LinkType -eq "Junction") { }
Чтобы проверить, является ли файл/папка «ReparsePoint» любого типа (Junction, SymbolicLink или HardLink):
if ((Get-Item -Path $Target -Force).LinkType) { }
Значение LinkType для обычного файла/папки представляет собой пустую строку, которая при использовании в качестве условия if в PS разрешается в False.
Get-ChildItem можно использовать для вывода списка всех папок Junction:
(Get-ChildItem -Path $Target -Force) | Where-Object { $_.LinkType -eq "Junction" }
Обратите внимание, что значение «SymbolicLink» одинаково для файла или папки, поэтому для отображения только символических ссылок на папки:
(Get-ChildItem -Path $Target -Directory -Force) | Where-Object { $_.LinkType -eq "SymbolicLink" }
Командлет Get-ChildItem (псевдоним: dir, ls, gci) теперь показывает атрибут ReparsePoint как l
в столбце Mode без какого-либо расширения. Но он не будет отображать «HardLink» и показывает l
как для Junction, так и для SymbolicLink:
> Get-ChildItem -Path $Target -Force
Directory: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--hsl 2018-04-12 01:45 All Users
d-rh-- 2018-05-09 06:12 Default
d--hsl 2018-04-12 01:45 Default User
d----- 2018-06-24 03:05 Papo
d-r--- 2018-07-27 07:12 Public
- LinkType не работает с папками со специальными разрешениями внутри \Users и \Users\, хотя Get-ChildItem, как показано выше, работает и показывает для них
l
. - Remove-Item имеет проблемы. Он не может удалить Junction, и, если принудительно, удалит исходное содержимое вместе с ним. Говорят, что это будет исправлено в будущей версии PS v6.
Использование этих улучшенных или современных стандартных командлетов имеет некоторые преимущества по сравнению с предыдущими методами, описанными в более старых ответах здесь.
Он различает Junction и Symbolic Link
Если OP хочет проверить, является ли папка Junction, проверка по свойству Attribute приведет к ложному срабатыванию для символической ссылки папки.обнаруживает жесткую ссылку.
LinkType — это [String], в отличие от свойства Attributes, которое имеет тип [FileAttributes] и требует .ToString() или использования -band
LinkType
не работает не только с пользователями. Например, на моем компьютере с W10 с PS 5.1 LinkType имеет значение null как для C:\Documents and Settings, так и для C:\ProgramData\Desktop, тогда как dir /aL
(командная строка, а не PowerShell) указывает, что они оба являются точками соединения. LinkType
просто не кажется надежным для точек повторной обработки.
- person NewSites; 18.10.2019
К вашему сведению, если вы используете расширения сообщества PowerShell, эта информация доступна в виде вывода (и в качестве свойства примечания ) на выходе Get-ChildItem:
21> gci .\Roaming\Microsoft\eHome
Directory: Microsoft.PowerShell.Core\FileSystem::C:\Users...
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2/15/2010 12:18 AM <DIR> DvdCoverCache
d---- 8/9/2009 1:10 AM <SYMLINK> DvdInfoCache [\...
d---- 8/8/2009 11:51 PM <DIR> DvdInfoCache.orig
d---- 10/22/2009 7:12 PM <DIR> mcl_images
Однако для программного доступа я бы получил доступ к информации через свойство Attributes, как предлагает другой плакат.
Если у вас есть расширения сообщества PowerShell, которые я бы рекомендовал, если вы работаете с соединениями, вы можете сделать следующее, чтобы определить, является ли папка соединением или нет:
Import-Module pscx
if ((Get-Item *test_folder*).ReparsePoint){
Write-Host "YES"
}
Попробуй это:
$TargetAttributes = (Get-Item -Path $Target -Force).Attributes.ToString()
if ($TargetAttributes -match "ReparsePoint") {
if ($TargetAttributes -match "Archive") {
Write-Output ("Link to a file.")
} else {
Write-Output ("Link to a folder.")
}
} else {
Write-Output ("Normal File or Folder.")
}