Во-первых, как вы заметили, существуют ограничения для персонажей. Общая длина пути не может превышать 256 символов для любого файла в последнем каталоге, а длина каталога не может превышать 248 символов. Вы хотите добавить некоторые проверки для этого. Вначале это означает, что имя папки из 256 символов никогда не должно работать. Когда-либо.
Если вы знаете, что такое полный путь, и просто хотите пройти вверх по структуре каталогов к корневой папке, вы можете использовать свойство .Parent
для объекта папки.
Ниже приведено лишь подтверждение концепции, которая создаст структуру папок с вложенным в нее файлом, а затем с учетом начальной и конечной точки будет работать из самой глубокой вложенной папки, указанной в целевой папке, переименовывая папки в это продолжается до тех пор, пока не достигнет ограничения по длине.
$NewName = 'ReallyExtremelyLongFolderName'
Remove-Item C:\Test -Recurse -Force -ea 0
Remove-Item "C:\$NewName" -Recurse -Force -ea 0
$RootFolder = "C:\test"
$TargetFolder = 'C:\test\Test\Test\Test\Test\Test\Test\Test\test'
New-Item "C:\test\Test\Test\Test\Test\Test\Test\Test\test\Test\Some Long File.xlsx" -force |Out-Null
$LongestFileName = Get-ChildItem $TargetFolder -recurse | Sort {$_.FullName.Length} | Select -last 1 -ExpandProperty FullName
$MaxLength = If((Get-Item $LongestFileName).PSIsContainer){248}Else{256}
$CurrentFolder = Get-Item $TargetFolder
$NewTarget = $TargetFolder
$VerbosePreference='Continue'
Do{
Write-Verbose "Working on: $($CurrentFolder.FullName)"
$NewTargetTmp = $NewTarget.Replace($CurrentFolder.FullName,(Join-Path (split-path $CurrentFolder.FullName) $NewName))
#Check new path for existing longest path
Write-Verbose "Checking new longest path: $($LongestFileName.Replace($NewTarget,$NewTargetTmp))`nLength: $($LongestFileName.Replace($NewTarget,$NewTargetTmp).length)`n"
If(($LongestFileName=$LongestFileName.Replace($NewTarget,$NewTargetTmp)).Length -gt $MaxLength) {Write-Warning "New target path to deepest nested file/folder too long:`n$LongestFileName";break}
$CurrentFolder | Rename-Item -NewName $NewName
$NewTarget = $NewTargetTmp
$CurrentFolder = Get-Item $CurrentFolder.Parent.FullName
}Until($CurrentFolder.FullName -eq $RootFolder)
$VerbosePreference='SilentlyContinue'
Вы можете закомментировать $VerbosePreference
строк (есть 2 из них), чтобы сделать это менее спам.