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:SystemCurrentControlSetControlFileSystem' -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 '\?UNC127.0.0.1c$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 '\?UNC127.0.0.1This 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:\__tmpDummy Folder11'
#UNC - tested on a UNC share path
CreateVeryLongPath -Root '\ServerNameShareName' -FolderName 'This is a folder' -IsUNC
QueryVeryLongPath -Root '\ServerNameShareName' -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