Hello World,
This post addresses a quite known issue related to file path length limitation in NTFS filesystem. Every system administrator or file server administrator has encountered this issue while trying to delete folders or files or simply restructuring file and folder structure. When trying to manipulate some files located in a deep folder structure, you might receive the infamous error message : Path Too Long
Click on Picture for Better Resolution
In this post, we will provide a quick way to overcome this NFTS File system limitation. In fact, we will present multiple options that you might be able to use within your environment and which will help your work when dealing with File Services….
So, Let’s go….
Overview
Our Scenario
We have been asked to provide some reporting on File server and disk space used by some specific divisions. No Third party tools available or authorized. Again, the best option would be to use PowerShell scripting capabilities. Using well-known cmdlet, we came up with this simple one-liner (this is used for demonstration purposes as a more complex script has been written)
(get-ChildItem -Force E:\DivisionA -Recurse | measure-Object Length -s ).sum/1MB
When running this command against the specified folders, we should obtain the total size of the folder and its contents (subfolders). Initially, the command was working fine. Eventually, we came up with a folder containing a lot of data but also really long file names !!! The infamous error came up also in PowerShell : The specified path or file or both are too long.
Click on Picture for Better Resolution
Obviously, this will make our work a little bit more complicated as we now have to identify which path is too long . There is also a high chance that other subfolders might contains really long file path.
To overcome this situation, there are a lot of tips and trick on Internet. You could try to shorten the path using UNC network path or you can use the old (but still useful) subst command or using third party tools. A lot of options exists. However, our goal was to provide a rather simple workaround to the situation and have it working (almost) 100 % of the time
Possible Workarounds
Using only Windows Settings and PowerShell technology, it would be possible to overcome this long path limitation but some of the solutions presented hereafter requires specific Operating System Version.
If you are running Windows 2016 or later
If you are running a modern operating system, you will have basically two options.
- Enabling support for long File Path through a GPO or
- via PowerShell cmdlet Get-ChildItem
Option 1 – Enable Long File Path Support
By default, Windows 2016 Server and later Operating Systems provide support file path up to 260 Characters. Windows 2016 Server and later can now support longer file path if the feature is enabled through Group Policy (or possibly through registry keys). This is quite a welcome feature but surprisingly not well known by a lot of system admins. To enable the feature through GPO, you create a group policy and you then expand Computer Settings > Administrative Templates > System > FileSystem and you will see the option Enable Win32 Long Paths
Click on Picture for Better Resolution
Next time you will work on a File Server that has long file path you should not get error message when trying to obtain file size information.
Note :
You can enable this feature via registry key by navigating to HKLM\SYSTEM\CurrentControlSet\Control\FileSystem and find the set value to 1 for the entry LongPathsEnabled. If you do not see the key, create it as a DWORD (32bit)
Click on Picture for Better Resolution
Option 2 – Using PowerShell
This option is more interesting for us. Without enabling long path support at the operating system, it’s possible to use the PowerShell cmdlet Get-ChildItem to overcome the long path limitation. You can use the command to access local files or Network Files through UNC Path. The following command and syntax should not complain about long path files…..
#If you are accessing files locally get-childItem -LiteralPath \\?\e:\TopFolders\ #If you are accessing files through network Share get-childItem -LiteralPath \\?\UNC\MyFileServerHostName\Share\
Using the LiteralPath option, you will be able to access long file paths through your scripts. This option is quite cool because it requires zero configuration changes at the operating system level. You just need to adapt your script accordingly.
If you are running Windows 2012 R2
Surprisingly (or not), a lot of organizations are still running on Windows 2012 R2. Actually, we just finished some Windows 2008 R2 migration to more recent Operating system. Usually, legacy applications can explain the use of older Operating system but also because people do not really like introducing changes in a perfectly working fine infrastructure. Anyway, coming back to our discussion, it’s should be quite clear that Windows 2012 R2 cannot take advantage of the new Enable Long Path feature as the GPO/setting is not supported.
We have to fall back to option 2 which is the PowerShell method. To be able to use this option, the Windows 2012 R2 machine needs to be running a supported version. To check which version of PowerShell you are running, open a PowerShell command Prompt and issue the following command
$PsVersionTable
Click on Picture for Better Resolution
If you see that version is set to 4.0, you will need to install the WMF 5.1 package (manually or through patch management solution) in order to have the -LiteralPath working as expected. The WMF 5.1 package will basically update the PowerShell version already installed on your system and expose the most recent PowerShell cmdlets and improvements that have been already integrated in Windows 2016 Operating system. The package can be found and downloaded on Microsoft Web site (at this location). In our scenario, we will install the update manually. Double-click on the downloaded executable. You will see something like this
Click on Picture for Better Resolution
Proceed with the installation. Wait for Completion. At the end, you will need to reboot the machine in order to apply the changes. You might need to plan this reboot based on your internal procedure
Click on Picture for Better Resolution
When the installation is completed, you can check again the PowerShell Version that available on your system.
Click on Picture for Better Resolution
When this is done, you will be able to issue the following PowerShell commands which should overcome the long path file limitation….
#If you are accessing files locally get-childItem -LiteralPath \\?\e:\TopFolders\ #If you are accessing files through network Share get-childItem -LiteralPath \\?\UNC\MyFileServerHostName\Share\
All Windows Versions
It’s also possible to bypass the long path limitations without updating Powershell Version or enabling the feature on Recent operating system. The following approach simply uses the Robocopy builtin tool that can deal with Long Path files. The following script demonstrate how to report folder size on a specific server even if long path exists.
#------------------------------------------------------------------------------------------- # ScriptName : FolderSizeReport.ps1 # Description : Combining robocopy and Powershell to Report folders size while avoiding the # long Path file error # Version : 1.0 # Note : Original script can be found at learn-powershell.net #------------------------------------------------------------------------------------------- $data=Get-ChildItem 'c:\windows\System32' $data | foreach { $item = $_.FullName $params = New-Object System.Collections.Arraylist $params.AddRange(@("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0")) $countPattern = "^\s{3}Files\s:\s+(?<Count>\d+).*" $sizePattern = "^\s{3}Bytes\s:\s+(?<Size>\d+(?:\.?\d+)).*" $return = robocopy $item NULL $params If ($return[-5] -match $countPattern) { $Count = $matches.Count } If ($Count -gt 0) { If ($return[-4] -match $sizePattern) { $Size = $matches.Size } } Else { $Size = 0 } $object = New-Object PSObject -Property @{ FullName = $item Count = [int]$Count Size = ([math]::Round($Size/1GB,2)) } $object.pstypenames.insert(0,'IO.Folder.Foldersize') Write-host "$($object.FullName);$($object.Count);$($object.Size) GB;$($_.LastAccessTime);$($_.LastWriteTime)" $Size=$Null }
Final Notes
This is it for this post ! Through this post, we have demonstrated how to quite easily overcome the Long path limitations found in Windows Operating Systems. Recent Operating systems version can handle in a better way this problem. Indeed, since Windows 2016, it’s possible to enable a feature that would allow the Operating System to overcome the 260 characters limitations in path files. Recent PowerShell version (5.1 or later) also include additional features that help overcome the long path limitation.
To conclude, it would be good to educate users in order to teach them how to save their files and using proper (and shorter) naming conventions
Hope you enjoyed this post
Till next time
See ya
Thanks for the great info and on the other hand long path fixer, Gs Richcopy 360, or Long Path Tool are the superstars for this issue
Thank you, this solutions works for me and save a lot of time for me. Thank you so much!!!
Thanks for this, now using “-LiteralPath” in a script to remotely collect information about file server shares and access rights on folder levels. Before making that change my script ran into problems with Get-ChildItem and Get-Acl for very deep folder hierarchies and long file/directory names.
@Marcus,
Thank you for visiting our blog and providing feedback. Happy to see that you have found our post useful and it solved your issue : )
till next time
See ya