Search code examples
powershellfilemove

Move files from subfolders to parent folders cmd powershell


I have been trying to move files from multiple subfolders to their parent folders by running the following .bat and .ps1 scripts:

1.  forfiles /s /m *.* /c "cmd /c move @path %CD%"
2. powershell -Command "gci *.* -R | mv -D ."
3. Get-ChildItem -File -Recurse | Move-Item -Destination .
4. Get-ChildItem -File -Recurse | Move-Item -Destination ..

The folders structure is 'Top folder' and two subfolders: Top_folder\Subfolder_1\Subfolder_2. The aim is to run script from main 'top folder' and having all the files from Subfolder_2 moved to Subfolder_1. The main folder have a numerous

Subfolder_1\Subfolder_2
Subfolder_1\Subfolder_2
...
Subfolder_1\Subfolder_2

folders. The above codes move files either to the current folder where script locates or into parent folder (up from the script location), depends on wildcard '..' or '.'

Any thoughts/ideas would be greatly appreciated.


Solution

  • The solution has been kindly provided by @francishagyard2 here

    # Root path is referenced to script's location by means of variable $PSScriptRoot. That's how I use ones in most cases.
    $RootPath = $PSScriptRoot
    
    # Get list of parent folders in root path
    $ParentFolders = Get-ChildItem -Path $RootPath | Where {$_.PSIsContainer}
    
    # For each parent folder get all files recursively and move to parent, append number to file to avoid collisions
    ForEach ($Parent in $ParentFolders) {
        Get-ChildItem -Path $Parent.FullName -Recurse | Where {!$_.PSIsContainer -and ($_.DirectoryName -ne $Parent.FullName)} | ForEach {
            $FileInc = 1
            Do {
                If ($FileInc -eq 1) {$MovePath = Join-Path -Path $Parent.FullName -ChildPath $_.Name}
                Else {$MovePath = Join-Path -Path $Parent.FullName -ChildPath "$($_.BaseName)($FileInc)$($_.Extension)"}
                $FileInc++
            }
            While (Test-Path -Path $MovePath -PathType Leaf)
            Move-Item -Path $_.FullName -Destination $MovePath
        }
    }