Question

I have no problem adding sequential prefixes to filenames. The following works great on the top directory in question.

$path="E:\path\newtest1"
$count=4000
Get-ChildItem $path -recurse | Where-Object {!$_.PSIsContainer -and $_.Name -NotMatch '^\d{4}\s+'}  | ForEach -Process {Rename-Item $_ -NewName ("$count " + $_.name -f $count++) -whatif}

BUT if there are files in subfolders within the top directory, these are all completely missed. Whatif reports that for any deeper file it "does not exist".

I have tried the following, based on looking at some pages on other recursion problems, but as you can probably guess I have no clue what it is doing. Whatif shows that it does at least pickup and rename all the files. But the following does it too much and makes multiple copies of each file with each number:

$path="E:\path\newtest1"
$count=4000
Get-ChildItem  -recurse | ForEach-Object {  Get-ChildItem $path | Rename-item -NewName    ("$count " + $_.Basename  -f $count++) -whatif}

Really keen to get some guidance on how to get the first of these two snippets to work to find all files in all subdirectories and rename them with sequential number prepended.

Was it helpful?

Solution

Try it like so:

Get-ChildItem $path -recurse -file | Where Name -NotMatch '^\d{4}\s+' | 
    Rename-Item -NewName {"{0} $($_.name)" -f $count++} -whatif

When you supply $_ as an argument (not a pipeline object), that gets assigned to the Path parameter which is of type string. PowerShell tries to convert that FileInfo object to a string but unfortunately the "ToString()" representation of files in nested folders is just the filename and not the full path. You can see this by executing:

Get-ChildItem $path -recurse -file | Where Name -NotMatch '^\d{4}\s+' | ForEach {"$_"}

The solution is either to A) pipe the object into Rename-Item or B) use the FullName property e.g. Rename-Item -LiteralPath $_.FullName ....

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top