Forum Discussion

DavidMAshworth's avatar
DavidMAshworth
Copper Contributor
Feb 02, 2023

Having trouble moving multiple folders up a level

Hi all,

 

I have a requirement to change a file structure for a client. Basically they want all files within an "FYxx" folder to be moved one level up while maintaining the folder structure.

 

I developed a script to do this for one specified folder but now I want to expand that to all folders in the directory. This is the original script that works using one folder:

 

# Define the source directory
$source = "C:\SP\AGA"

# Get all the FY folders in the source directory
$fyFolders = Get-ChildItem -Path $source -Directory | Where-Object { $_.Name -like "FY*" }

# Loop through each FY folder
foreach ($fyFolder in $fyFolders) {
    # Get all the subfolders in the FY folder
    $subfolders = Get-ChildItem -Path $fyFolder.FullName -Recurse -Directory

    # Get all the files in the FY folder
    $subfiles = Get-ChildItem -Path $fyFolder.FullName -Recurse -File

    # Combine the subfolders and files into one array
    $subitems = $subfolders + $subfiles

    # Loop through each subfolder and file
    foreach ($subitem in $subitems) {
        # Get the relative path to the subfolder or file
        $relativePath = $subitem.FullName.Substring($fyFolder.FullName.Length)

        # Move the subfolder or file to the parent folder
        Move-Item -LiteralPath $subitem.FullName -Destination ($fyFolder.Parent.FullName + $relativePath)
    }

    # Get the contents of the FY folder after all subfolders and files have been moved
    $contents = Get-ChildItem -Path $fyFolder.FullName

    # Check if the FY folder has no files
    if (!$contents.Where{ $_.PsIsContainer -eq $false }) {
        # Delete the FY folder if it has no files
        Remove-Item -Path $fyFolder.FullName -Recurse
    }
}

 

I then wanted to add a capability to scan the parent directory and use those results as the source. This is what I have but it doesn't actually do anything. It doesn't fail with an error it just does nothing:

 

# Define the path to the parent folder
$parentFolder = "C:\SP"

# Get all subfolders in the parent folder
$subFolders = Get-ChildItem -Path $parentFolder -Directory

# Loop through each subfolder
foreach ($subFolder in $subFolders) {
    # Get the source folder
    $source = $subFolder.FullName

    # Get all subfolders with "FY" in the name
    $fyFolders = Get-ChildItem -Path $source -Recurse | Where-Object { $_.PSIsContainer -and $_.Name -like "*FY*" }

    # Loop through each FY folder
    foreach ($fyFolder in $fyFolders) {
        # Get all items (files and subfolders) in the FY folder
        $items = Get-ChildItem -Path $fyFolder.FullName -Recurse -File -Directory

        # Move all items to the parent folder
        foreach ($item in $items) {
            $destination = Join-Path -Path $fyFolder.Parent.FullName -ChildPath $item.Name
            Move-Item -LiteralPath $item.FullName -Destination $destination
        }
    }

    # Delete all empty FY folders
    $emptyFyFolders = Get-ChildItem -Path $source -Recurse | Where-Object { $_.PSIsContainer -and $_.Name -like "*FY*" -and (!(Get-ChildItem -Path $_.FullName -Recurse)) }
    foreach ($emptyFyFolder in $emptyFyFolders) {
        Remove-Item -Path $emptyFyFolder.FullName -Force -Recurse
    }
}

 

Any idea where I am going wrong?

 

Thanks,
David

  • Vinod_5's avatar
    Vinod_5
    Copper Contributor
    Hi DavidMAshworth,

    Good day!

    According to your requirement the below script worked for me with my data.

    I used a different logic as I was unable to fetch required data from get-childitem in for loops as provided in your script.

    Please check with my script and let me know the result.

    I will be happy to try once again. Thank you.


    #Define the path to the parent folder
    $parentFolder = "C:\SP"
    cd $parentFolder
    $subFolders = Get-childItem  -path $parentFolder - Directory
    $fyFolders =  Get-childItem - path $subFolders - Recurse | where-object {$_. PSIsContainer - and $_.Name  -like  "*FY*"}
    $count = $fyFolders.count
    For ($i=0; $i -lt $count; $i++)
    {
    Move-Item - path $fyFolders[$i]. FullName - Destination $parentFolder

    }