Handling Path Too Long Exception with New-PSDrive

前端 未结 1 415
故里飘歌
故里飘歌 2020-12-14 03:14

I am recursing a deep folder structure in order to retreive all folder paths like so:

$subFolders = Get-ChildItem $rootFolder -Recurse -Directory  -ErrorVari         


        
相关标签:
1条回答
  • 2020-12-14 03:42

    There is a local policy that is now available since Windows anniversary update.

    Requirements are :

    • Windows Management Framework 5.1

    • .Net Framework 4.6.2 or more recent

    • Windows 10 / Windows server 2016 (Build 1607 or newer)

    This policy can be enabled using the following snippet.

    #GPEdit location:  Configuration>Administrative Templates>System>FileSystem 
    Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1
    

    Otherwise, you can actually get to the paths longer than 260 characters by making your call to the unicode version of Windows API.

    There's a catch though. This work only in Powershell 5.1 minimum.

    From there, instead of making your call the standard way:

    get-childitem -Path 'C:\Very long path' -Recurse  
    

    You will need to use the following prefix: \\?\

    Example

    get-childitem -LiteralPath '\\?\C:\Very long path' -Recurse 
    

    For UNC path, this is slightly different, the prefix being \\?\UNC\ instead of \\

    get-childitem -LiteralPath '\\?\UNC\127.0.0.1\c$\Very long path\' -Recurse
    

    Important

    When calling Get-ChildItem unicode version, you should use the -LiteralPath parameter instead of Path

    From Microsoft documentation

    -LiteralPath

    Specifies a path to one or more locations. Unlike the -Path parameter, the value of the -LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose them in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences.

    source

    Example

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

    output

    Here is the actual functional test I made to create the very long repository, query it to produce the output above and confirm I could create repository with more than 260 characters and view them.

    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
    

    Worth to mention

    During my research, I saw people mentioning using RoboCopy then parse its output. I am not particularly fond of this approach so I won't elaborate on it. (edit: Years later, I discovered that Robocopy is part of Windows and not some third-party utility. I guess that would be an ok approach too, although I prefer a pure Powershell solution)

    I also saw AlphaFS being mentionned a couple of time which is a library that allows to overcome the 260 characters limitation too. It is open sourced on Github and there's even a (I did not test it though) Get-AlphaFSChildItem built on it available on Technet here

    Other references

    Long Paths in .Net

    Naming Files, Paths, and Namespaces

    0 讨论(0)
提交回复
热议问题