如果文件夹是连接点,我如何在 PowerShell 代码中进行测试?
6 回答
If (Get-Item Test Folder ).Attributes.ToString().Contains("ReparsePoint"){ Code }
至少从 PowerShell v5.0 开始,对链接有更好的支持(或者 MS 称之为:Reparse Points)
链接的文章属于 WMF 5.0 类别,这可能意味着该方法自 PS v5.0 起可用。
这些功能包含在标准的 Get-Item、Get-ChildItem 中,因此不需要额外的步骤。它可以在任何当前的 PS 上使用。
LinkType 是 Object 上的 String 属性,由 Get-Item 和 Get-ChildItem 返回,
它可以具有以下四个值之一:''、'Junction'、'SymbolicLink'、'HardLink'。
要回答 OP 的问题,您可以使用以下命令检查文件夹是否为连接点:
if ((Get-Item -Path $Target -Force).LinkType -eq "Junction") { }
要检查文件/文件夹是否是任何类型(Junction、SymbolicLink 或 HardLink)的“ReparsePoint”:
if ((Get-Item -Path $Target -Force).LinkType) { }
普通文件/文件夹上的 LinkType 值是一个空字符串,当使用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" }
Cmdlet 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 版本中修复
与以前的方法相比,使用这些改进的或今天的标准 Cmdlet 具有一些优势,在此处的较旧答案中进行了描述。
它确实区分了 Junction 和 Symbolic Link
如果 OP 想要测试文件夹是否是 Junction,通过 Attribute 属性检查将导致文件夹符号链接的误报。检测硬链接。
LinkType 是 [String] 而不是 Attributes 属性,后者是 [FileAttributes] 类型并且需要 .ToString() 或使用 -band
这样做的方法是复制内置的文件系统格式化文件,对其进行修改以指示连接,然后使用Update-FormatData加载它:
从博客:
文件系统格式化规则在
$pshome\FileSystem.Format.ps1xml
. 我复制了这个,然后在元素 中将值为“Mode”的PropertyName[ViewDefinitions –> View –> TableControl –> TableRowEntries –> TableRowEntry –> TableColumnItems –> TableColumnItem]
的内容更改为以下内容:<ScriptBlock> "$($_.Mode)$(if($_.Attributes -band [IO.FileAttributes]::ReparsePoint) {'J'})" </ScriptBlock>
这会
$_.Attributes
针对 .NetSystem.IO.FileAttributes.ReparsePoint
枚举值对 DirectoryInfo 对象的 Attributes 属性 ( ) 进行按位与运算。如果结果不为零,它会在其他文件模式属性旁边显示一个“J”。接下来,像这样加载新的格式化文件:PS> Update-FormatData -PrependPath myFilesystem.format.ps1xml
PrependPath参数可确保在内置格式文件之前加载新的格式文件。
目录 alink 在模式列中有一个“J”,似乎有效!
它位于结点的模式列 J 中。
仅供参考,如果您碰巧正在运行PowerShell Community Extensions,则此信息可用作 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.")
}