gpt4 book ai didi

powershell - 使用 New-PSDrive 处理路径过长异常

转载 作者:行者123 更新时间:2023-12-04 00:06:28 26 4
gpt4 key购买 nike

我正在递归一个深层文件夹结构,以便像这样检索所有文件夹路径:

$subFolders = Get-ChildItem $rootFolder -Recurse -Directory  -ErrorVariable folderErrors | Select-Object -ExpandProperty FullName

注意:在我的例子中,$rootFolder 是一个网络共享。即“\\server\DeptDir$\somefolder”
$folderErrors变量正确捕获所有 FileTooLong 异常,因此我想使用长路径创建新的 PSDrive,以便递归这些长路径。

所以我使用这个 cmdlet 创建了一个新的 PSDrive:
new-psdrive -Name "long1" -PSProvider FileSystem -Root $folderErrors[0].CategoryInfo.TargetName

但是,在创建新的 PSDrive 后,我仍然收到 PathTooLong 异常。
PS C:\>> cd long1:
PS long1:\>> dir
dir : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
At line:1 char:1
+ dir
+ ~~~
+ CategoryInfo : ReadError: (\\svr01\Dep...\Fibrebond ECO\:String) [Get-ChildItem], PathTooLongException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand

我认为没有其他方法可以解决这个问题。我做错了什么吗?当我在路径太长的位置创建驱动器时,为什么新的 PSDrive 会抛出 PathTooLong?

谢谢

最佳答案

自 Windows 周年更新以来,现在有一个本地策略可用。

要求是:

  • Windows 管理框架 5.1
  • .Net Framework 4.6.2 或更新版本
  • Windows 10/Windows server 2016(内部版本 1607 或更高版本)

  • 可以使用以下代码段启用此策略。
    #GPEdit location:  Configuration>Administrative Templates>System>FileSystem 
    Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1

    否则,您实际上可以通过调用 unicode 版本的 Windows API 来获得超过 260 个字符的路径。

    不过有一个问题。
    此作品仅在 电源外壳 5.1 最低限度。

    从那里开始,而不是以标准方式调用电话:
    get-childitem -Path 'C:\Very long path' -Recurse  

    您将需要使用以下前缀: \\?\
    例子
    get-childitem -LiteralPath '\\?\C:\Very long path' -Recurse 

    对于 UNC 路径,这略有不同,前缀为 \\?\UNC\而不是 \\
    get-childitem -LiteralPath '\\?\UNC\127.0.0.1\c$\Very long path\' -Recurse

    重要

    调用 Get-ChildItem时unicode 版本,您应该使用 -LiteralPath参数而不是 Path
    来自 Microsoft 文档
    -LiteralPath
    指定一个或多个位置的路径。与 -Path 参数不同,-LiteralPath 参数的值完全按照键入的方式使用。没有字符被解释为通配符。如果路径包含转义字符,请将它们括在单引号中。单引号告诉 Windows PowerShell 不要将任何字符解释为转义序列。

    source

    示例
    (get-childitem -LiteralPath '\\?\UNC\127.0.0.1\This is a folder$' -Recurse) | 
    ft @{'n'='Path length';'e'={$_.FullName.length}}, FullName

    输出
    Get-Childitem with long paths

    这是我为创建非常长的存储库所做的实际功能测试,查询它以生成上面的输出并确认我可以创建超过 260 个字符的存储库并查看它们。
    Function CreateVeryLongPath([String]$Root,[Switch]$IsUNC,$FolderName = 'Dummy Folder',$iterations = 200) {
    $Base = '\\?\'
    if ($IsUNC) {$Base = '\\?\UNC\'}

    $CurrentPath = $Base + $Root + $FolderName + '\'

    For ($i=0;$i -le $iterations;$i++) {

    New-Item -Path $CurrentPath -Force -ItemType Directory | Out-Null
    $currentPath = $CurrentPath + $FolderName + '\'
    }
    }

    Function QueryVeryLongPath([String]$Root,[Switch]$IsUNC) {
    $Base = '\\?\'
    if ($IsUNC) {$Base = '\\?\UNC\';$Root = $Root.substring(2,$Root.Length -2)}

    $BasePath = $Base + $Root
    Get-ChildItem -LiteralPath $BasePath -Recurse | ft @{'n'='Length';'e'={$_.FullName.Length}},FullName
    }



    CreateVeryLongPath -Root 'C:\__tmp\' -FolderName 'This is a folder'
    QueryVeryLongPath -Root 'C:\__tmp\Dummy Folder11\'

    #UNC - tested on a UNC share path
    CreateVeryLongPath -Root '\\ServerName\ShareName\' -FolderName 'This is a folder' -IsUNC
    QueryVeryLongPath -Root '\\ServerName\ShareName\' -IsUNC

    值得一提

    在我的研究中,我看到有人提到使用 RoboCopy 然后解析它的输出。我不是特别喜欢这种方法,所以我不会详细说明。
    (编辑:多年后,我发现 Robocopy 是 Windows 的一部分,而不是某些第三方实用程序。我想这也是一个不错的方法,尽管我更喜欢纯 Powershell 解决方案)

    我也看到了 AlphaFS被提到了几次,这是一个允许克服 260 个字符限制的库。它是在 Github 上开源的,甚至还有一个(虽然我没有测试过) Get-AlphaFSChildItem建立在 Technet here 上可用

    其他引用资料

    Long Paths in .Net

    Naming Files, Paths, and Namespaces

    关于powershell - 使用 New-PSDrive 处理路径过长异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46308030/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com