我正在递归深层文件夹结构,以便像这样检索所有文件夹路径:
$subFolders = Get-ChildItem $rootFolder -Recurse -Directory -ErrorVariable folderErrors | Select-Object -ExpandProperty FullName
注意:在我的情况下,$ rootFolder是一个网络共享。即“\\ server \ DeptDir $ \ somefolder”
$folderErrors
变量正确捕获所有FileTooLong异常,因此我想使用长路径创建新的PSDrives以递归这些长路径。
所以我使用这个cmdlet创建了一个新的PSDrive:
new-psdrive -Name "long1" -PSProvider FileSystem -Root $folderErrors[0].CategoryInfo.TargetName
但是,在创建新的PSDrive后,我仍然会收到PathTooLong Exceptions。
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?
由于
答案 0 :(得分:27)
自Windows周年更新以来,现在可以使用本地策略。
要求是:
Windows Management Framework 5.1
.Net Framework 4.6.2或更新的
Windows 10 / Windows server 2016(Build 1607或更新版本)
可以使用以下代码段启用此政策。
#GPEdit location: Configuration>Administrative Templates>System>FileSystem
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1
否则,通过调用Windows API的unicode版本,您实际上可以访问超过260个字符的路径。
虽然有一个问题。 这项工作仅限于 Powershell 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不要将任何字符解释为转义序列。
示例
(get-childitem -LiteralPath '\\?\UNC\127.0.0.1\This is a folder$' -Recurse) |
ft @{'n'='Path length';'e'={$_.FullName.length}}, FullName
这是我为创建非常长的存储库而进行的实际功能测试,查询它以生成上面的输出并确认我可以创建超过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然后解析其输出。我不是特别喜欢这种方法,所以我不会详细说明。
我还看到AlphaFS被提及了几次,这是一个允许克服260个字符限制的库。它是在Github上开源的,甚至还有一个(我没有测试过它)Get-AlphaFSChildItem
建立在它上面的Technet here
其他参考