Проверить в коде PowerShell, является ли папка точкой соединения?

Как я могу проверить в коде PowerShell, является ли папка точкой соединения?


person Serge van den Oever    schedule 22.02.2010    source источник
comment
Вы собираетесь отметить сообщение как правильный ответ?   -  person Chris Jones    schedule 24.02.2010


Ответы (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) по отношению к значению перечисления .Net System.IO.FileAttributes.ReparsePoint. Если результат не равен нулю, он отображает «J» рядом с другими атрибутами режима файла. Затем загрузите новый файл форматирования следующим образом:

 PS> Update-FormatData -PrependPath myFilesystem.format.ps1xml

Параметр PrependPath обеспечивает загрузку нового файла форматирования перед встроенными файлами форматирования.

Ссылка на каталог имеет «J» в столбце режима, похоже, работает!

Он находится в столбце режима J для перекрестка.

person Chris Jones    schedule 22.02.2010
comment
Спасибо, Крис, это именно то, что мне нужно! - person Serge van den Oever; 04.03.2010

If (Get-Item Проверить папку).Attributes.ToString().Contains("ReparsePoint"){Код}

person USMCDragon75    schedule 24.07.2013
comment
Это единственное решение, которое не требует изменения файлов конфигурации PowerShell или использования сторонних расширений. Альтернативная версия: if ((Get-Item Test Folder).Attributes -match [System.IO.FileAttributes]::ReparsePoint){Code} - person Olaf Hess; 20.08.2014
comment
ОП попросил программное решение, и это именно то, что нужно. - person jpaugh; 22.01.2019
comment
Это тест для любого типа точек повторной обработки, и он будет верен для других точек повторной обработки, не являющихся соединениями, таких как символические ссылки NTFS и точки монтирования тома. См. ответ папы, чтобы узнать, как различать различные типы точек повторной обработки в последних выпусках PowerShell. - person Anthony Geoghegan; 09.12.2020

По крайней мере, начиная с 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

person papo    schedule 27.07.2018
comment
LinkType не работает не только с пользователями. Например, на моем компьютере с W10 с PS 5.1 LinkType имеет значение null как для C:\Documents and Settings, так и для C:\ProgramData\Desktop, тогда как dir /aL (командная строка, а не PowerShell) указывает, что они оба являются точками соединения. LinkType просто не кажется надежным для точек повторной обработки. - person NewSites; 18.10.2019
comment
Очень исчерпывающий ответ, который должен быть оценен выше для всех, кто использует современную версию PowerShell. - person Anthony Geoghegan; 09.12.2020

К вашему сведению, если вы используете расширения сообщества 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, как предлагает другой плакат.

person Keith Hill    schedule 22.02.2010

Если у вас есть расширения сообщества PowerShell, которые я бы рекомендовал, если вы работаете с соединениями, вы можете сделать следующее, чтобы определить, является ли папка соединением или нет:

Import-Module pscx
if ((Get-Item *test_folder*).ReparsePoint){
    Write-Host "YES"
}
person David Wassman    schedule 23.06.2011

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

$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.")
}    
person Ralph Lee    schedule 06.04.2018