Problem:
Error when trying to rename files manually:
‘The source files name(s) are larger than is supported by the file system…’
Reasons:
- Parent folder must be less than 248 characters
- Filename and path must be less than 260 characters
Requirements:
– Windows Management Framework 5.1
– .Net Framework 4.6.2 or more recent
– Windows 10 / Windows server 2016 (Build 1607 or newer)
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1
# This function increases the default windows 260 characters path length limit to 1024
Function remove260CharsPathLimit([string]$computerName=$env:computername){
$osVersion=[System.Environment]::OSVersion.Version
$dotNetVersion=(get-itemproperty 'REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\' -Name "Version").Version
$windowsManagementFramework=$PSVersionTable.PSVersion
$osFeasible=$osVersion -ge [version]'10.0.1607'
$dotNetFeasible=$dotNetVersion -ge [version]'4.6.2'
$windowsFrameworkFeasible=$windowsManagementFramework -ge [version]'5.1'
if(!$osFeasible){
write-warning "OS Version $osVersion cannot be registry fixed to work with long file paths"
}
if(!$dotNetFeasible){
write-warning "Dot Net Version $dotNetVersion cannot be registry fixed to work with long file paths"
}
if(!$windowsFrameworkFeasible){
write-warning "Windows Management Framework $windowsManagementFramework cannot be registry fixed to work with long file paths"
}
if($osFeasible -and $dotNetFeasible -and $windowsFrameworkFeasible){
# Declare static variables
$registryHive="SYSTEM\CurrentControlSet\Control\FileSystem"
$keyName = 'LongPathsEnabled'
$value= 1
$remoteRegistry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$computerName)
$currentValue=$remoteRegistry.OpenSubKey("$registryHive\$keyName").GetValue($keyName)
if($currentValue -ne $value){
$remoteHive = $remoteRegistry.OpenSubKey($registryHive,$True)
$remoteHive.CreateSubKey($keyName)
$remoteKeyValue = $remoteRegistry.OpenSubKey("$registryHive\$keyName",$True)
$remoteKeyValue.SetValue($keyName,$value)
# Validation
$resultKey=$remoteRegistry.OpenSubKey("$registryHive\$keyName")
if($resultKey.GetValue($keyName) -eq $value){"\\$computerName\HKLM\$registryHive\$keyName has been added successfully."}
}else{
write-host "$computername already has $keyName set as $value"
}
return $true
}else{
return $false
}
}
remove260CharsPathLimit
# This reverses the effects of that previous function
Function restore260CharsPathLimit{
param([string]$computerName=$env:computername)
$registryHive= "SYSTEM\CurrentControlSet\Control\FileSystem"
$keyName = "LongPathsEnabled"
$result=REG DELETE "\\$computerName\HKLM\$registryHive" /v $keyName /f
if($result){"\\$computerName\HKLM\$registryHive\$keyName has been removed successfully."}
}
Other workarounds:
# Older versions of Windows - workaround
$sourceFolder='SourceFolder'
$destinationDirectory='DestinationFolder'
ROBOCOPY $sourceFolder $destinationDirectory /E /w:0 /r:0 /xj /b
ROBOCOPY $sourceFolder $destinationDirectory /E /w:0 /r:0 /xj /b /Copy:S /IS /IT
# save and restore permission
icacls "$sourceFolder" /save C:\ACL_Source /T
icacls "$destinationDirectory" /restore C:\ACL_Source
# Shorten the file name
$filePath='LongFilePathAndName'
$parentFolder=split-path $filePath -parent
$fileName=split-path $filePath -leaf
$removeChars=' ','and','to','&'
$x=$fileName
$truncatedFileName=.{$removeChars|%{$x=$x.Replace($_,'')};$x}
subst x: $parentFolder
rename-item x:\$fileName -NewName $truncatedFileName
cd c:\
subst x: /d
Categories: