Powershell “错误”;找不到路径的一部分“;在现有文件上设置属性时

Powershell “错误”;找不到路径的一部分“;在现有文件上设置属性时,powershell,Powershell,我编写了一个powershell脚本,将R/H/S属性从指定根路径集中的所有文件中剥离。有关守则如下: $Mask = [System.IO.FileAttributes]::ReadOnly.Value__ -bor [System.IO.FileAttributes]::Hidden.Value__ -bor [System.IO.FileAttributes]::System.Value__ Get-ChildItem -Path $Paths -Force -Recurse -Error

我编写了一个powershell脚本,将R/H/S属性从指定根路径集中的所有文件中剥离。有关守则如下:

$Mask = [System.IO.FileAttributes]::ReadOnly.Value__ -bor [System.IO.FileAttributes]::Hidden.Value__ -bor [System.IO.FileAttributes]::System.Value__
Get-ChildItem -Path $Paths -Force -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
    $Value = $_.Attributes.value__
    if($Value -band $Mask) {
        $Value = $Value -band -bnot $Mask
        if($PSCmdlet.ShouldProcess($_.FullName, "Set $([System.IO.FileAttributes] $Value)")) {
            $_.Attributes = $Value
        }
    }
}
这很好,但在处理一个非常大的文件夹结构时,我遇到了如下错误:

Exception setting "Attributes": "Could not find a part of the path 'XXXXXXXXXX'."
At YYYYYYYYYY\Grant-FullAccess.ps1:77 char:17
+                 $_.Attributes = $Value
+                 ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting
我觉得这很奇怪,因为被操纵的
FileInfo
对象肯定存在,因为它来自文件搜索

我不能给出文件名,因为它们是机密的,但我可以说:

  • 它们的长度为113-116个字符
  • 所涉及的唯一字符集是
    %()+-.0123456789ABCDEFGIKLNOPRSTUVWX
    ,这些字符在文件名中都是非法的
  • 由于URL编码的空格(
    %20
    )而存在
    %
    字符

你有什么建议来解释这可能是什么原因吗?我假设如果完整路径太长,或者我没有文件的写入权限,那么会抛出一个更合适的错误。

不管错误消息的措辞如何,这毕竟是一个长路径问题。对产生相同错误的文件进行简单的
Get ChildItem
搜索。我终于找到了错误消息中提到的文件,并测量了它们的总路径长度。超过260个字符

我尝试在路径中添加
\\?\
前缀,但powershell似乎不喜欢这种语法

幸运的是,该脚本正在Windows 2016上使用,因此我尝试启用组内策略。这就解决了整个问题。

如中所述,问题原来是一条很长的路径(比传统限制的259个字符长)

除了通过组策略启用长路径支持之外,您还可以通过注册表在每台计算机上启用长路径支持,如下所示,这需要以提升运行(管理员身份):

#注意:必须以管理员身份运行。
#更改将在今后的会议上生效。
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem LongPathEnabled 1
通过
0
关闭支持


但是,即使关闭了支持长路径的功能,也可以处理长路径:

  • 在Windows PowerShell中(PowerShell版本5.1之前),必须使用长路径选择加入前缀
    \\?\
    ,如下所述

  • PowerShell[Core]v6+中,不需要额外的工作,因为它始终支持长路径-您不需要打开支持系统范围,也不需要下面讨论的长路径前缀

    • 注意事项:虽然您原则上也可以在PowerShell[Core]中使用
      \\?\
      ,但从v7.0.0-rc.2开始,对它的支持是不一致的;看
重要:前缀
\\?\
仅在以下条件下有效:

  • 前缀路径必须是完整(绝对)规范化路径(不得包含
    组件)

    • 例如,
      \\?\C:\path\to\foo.txt
      有效,但
      \\?\。\foo.txt
      无效
    • 此外,如果路径是UNC路径,则该路径需要不同的形式:
      • \\?\UNC\\\…
      • 例如,
        \\server1\share2
        必须表示为
        \\?\UNC\server1\share2

这些是UNC路径(\\server\share\restofpath)还是本地路径?@mklement0:我的目的是处理目录和文件,但感谢您的提示。@mklement0:如果是长路径前缀,我现在怀疑这是一个长路径问题。我今天就试试。@Theo:路径将始终在本地驱动器上。
\\?\
确实适用于
获取项
/
获取子项
,但仅适用于完整的、规范化的路径。在PowerShell Core中,它们仅在使用
-LiteralPath
时才起作用,不幸的是,请参阅我的答案。奇怪的是,您最初在
$\uAttributes=$Value
中遇到了一个错误,没有显式的路径参数;这几乎表明
.Attributes
属性实现中存在一个bug,但我无法重新创建它。