Search code examples
powershell-2.0rename-item-cmdlet

Append ".backup" to all files, folders and subfolders in Powershell 2.0


I want to append ".backup" to all file and folder names (including subfolders and files in subfolders) using Powershell v2.0.

I came up with this script:

$origin = get-childItem -recurse | ?{ !( $_.name -like "*.backup" ) } 
$folders = $origin | ?{ $_.PSIsContainer }
$files =  $origin | ?{ ! $_.PSIsContainer }
$files | rename-item -force -newname { $_.name + '.backup' }
$folders | rename-item -force -newname { $_.name + '.backup' }

But I get this error for many items, stating the path is wrong:

Rename-Item : Cannot rename because item at 'Microsoft.PowerShell.Core\FileSystem::E:\backup\test.backup\subfolder.backup\proc 1\backup\example.docx' does not exist.
At line:1 char:21
+ $files | rename-item <<<<  -force -newname { $_.name + '.backup' }
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

But such file (example.docx) exists at that path, nonetheless.

Why is that error thrown? And what is the correct code for appending '.backup' to files and folders in PS 2.0? Thanks for any ideas!

EDIT: I don't think my question is a duplicate of When renaming a file with PowerShell, how do I handle filenames with "["? for 2 reasons: 1- the aims are different (just look at the titles); 2- that thread doesn't provide me code to do what I want, even though it's a good starting point (that's why I had linked to it in my answer). My question might be irrelevant but it took me some hours to figure out, so maybe I can spare someone some hours of frustration. But my question is badly formulated, I'll rework it now.


Solution

  • I found out it's a bug in Powershell prior to v. 3.0 in the Rename-Item cmdlet (see: When renaming a file with PowerShell, how do I handle filenames with "["? ). The only work around I found is to use Move-Item instead.

    Here's the full script I came up with:

    $path = 'E:\backup'
    $origin = get-childItem -path $path -recurse -exclude *.backup
    $folders = $origin | ?{ $_.PSIsContainer }
    $files =  $origin | ?{ ! $_.PSIsContainer }
    $files | %{ move-item -force -literalpath $_.fullname -destination ($_.fullname + '.backup') }
    $folders | sort-object -descending -property fullname | %{ move-item -force -literalpath $_.fullname -destination ($_.fullname + '.backup') }
    

    Anyone has a better code? Otherwise I'll mark it as "solved".