Powershell - Add Parent Folder Name to Each Folder

Dan CS 20 Reputation points
2023-04-05T11:17:24.82+00:00

Hi friends,

I created a powershell script to add the parent folder name of each folder.

I worked since yesterday trying to make this script.

It works but it also gives errors

I have tried so many different ways to make this a good script. Is there a better way for me to add parent folder names to each folder?


$Source_Folder='C:\Users\Dan\Desktop\test'
foreach($subfolder in (Get-ChildItem $Source_Folder -Directory -Recurse )){

$subfolder_path = $subfolder.fullname                                                            #  Full path with / slashes
#Write-Host $subfolder_path

[string]$subfolder_name = $subfolder.name                                                        #  Folder Name
#Write-Host $subfolder_name

[string]$parent_folder  = $subfolder.Parent                                                      # Parent folder name
#Write-Host $parent_folder



# New Folder Name
[string] $new_name = $parent_folder + "___" + $subfolder_name
#Write-Host $new_name


Rename-Item $subfolder_path -NewName  $new_name    


#Rename-Item $subfolder_path -NewName  $new_name    -Whatif    # Tests before renaming


#------------------------------------------------------------------------

}

Example Errors Rename-Item : Cannot rename because item at 'C:\Users\Dan\Desktop\test\images\PD875' does not exist. Any improvements on my script will be so much help. Thank you

PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,174 questions
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 45,186 Reputation points
    2023-04-17T02:23:21.74+00:00

    See if this works any better:

    $Source_Folder = 'C:\T'
    $rootfolder = split-path $Source_Folder -Leaf   # get just the source folders name for use later
    $h = Get-ChildItem $Source_Folder -Dir -depth 3 # no need to go deeper than 3 levels
    $Groups = $h | Group-Object  -Property Parent   # group the Level 3 directories into a group named by their parent directory
    ForEach($L2group in $Groups){
            if ($L2group.Name -eq $rootfolder){
                continue                            # Skip the source folder
            }
            ForEach($L3directory in $L2group.Group){
                Rename-Item $L3directory.fullname -NewName  ("{0}___{1}" -f $L2group.Name,$L3directory.Name)    -Whatif
            }
        }
    
    1 person found this answer helpful.
    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Rich Matheisen 45,186 Reputation points
    2023-04-05T15:29:05.81+00:00

    I haven't run your code, but what looks to me to be happening is that you've created a static list of a folder hierarchy. Then you rename a subfolder in that hierarchy that may have its own set of subfolders. By the time you try to use the static information in your list, the folder you're attempting to rename no longer has the same "fullname" as it did when you created the static list.


  2. Rich Matheisen 45,186 Reputation points
    2023-04-06T14:23:21.8166667+00:00

    The Get-ChildItem cmdlet does a depth-first (as opposed to a "breadth-first") traversal of the target directory. Try doing your renaming bottom-up instead of top-down:

    $h = Get-ChildItem $Source_Folder -Directory -Recurse
    Foreach ($subfolder in ([Array]::Reverse($h)){
    

  3. Dan CS 20 Reputation points
    2023-04-17T08:22:49.34+00:00

    Thank you Rich, this is the correct system! I was using bulk rename utility to add the parent folder name but its so slow on large directories. I knew I could use powershell but no amount of google found me a simple answer on how to add the parent folder name at level 3. Thank you for your time and expertise in solving this powershell issue. I am very happy now :) I hope you have a fantastic week! Thanks again Dan