Intermittent Copy Issue

Intent:
The code is intending to amend the folder structure to inverse the order.
e.g.
From: G:\To Be Organised\Test\PID\Hello Pty Ltd*.*
To: G:\To Be Organised\Test\Hello Pty Ltd\PID*.*

The majority of files copy, but some do not. Some files seem to fail because they can’t be found. I suspected it was the 255 char length, but reviewing the folders that doesn’t seem to be the case. I’m hoping for a code review to make this work? It’s a one time use program, so it doesn’t have to be fast/efficient…

Many thanks,

$dest = "G:\To Be Organised\Test"
$tempOutput = "G:\To Be Organised\_TestOutput"

get-childitem -LiteralPath $dest -Directory |
    foreach{
            $ProductClass= $_.BaseName
                        
            get-childitem -LiteralPath $_.FullName -Directory | #get the insured names
            foreach{
                    $InsuredName = Split-Path -Path $_ -Leaf
                                        
                    $sourcePath = $_.FullName #Full directory path of the product class subdirectories
                    $destPath = [IO.Path]::Combine($tempOutput, $InsuredName, $ProductClass)             #change the destination path to be the new frankenstein output.
                    
                    $fileList = @(Get-ChildItem -Path "$($sourcePath)" -File -Recurse)
                    $directoryList = @(Get-ChildItem -Path "$($sourcePath)" -Directory -Recurse)
                    
                    Write-Host "Moving $($sourcePath) to $($destPath)"
                    ForEach($directory in $directoryList){
                    $directories = New-Item ($directory.FullName).Replace("$($sourcePath)",$destPath) -ItemType Directory -ea SilentlyContinue
                                             }
                    ForEach($file in $fileList){
                                                try {
                                                    Move-Item -Path $file.FullName -Destination ((Split-Path $file.FullName).Replace("$($sourcePath)",$destPath)) -Force -ErrorAction Stop
                                                    }
                                                catch{
                                                      Write-Warning "Unable to move '$($file.FullName)' to '$(((Split-Path $file.FullName).Replace("$($sourcePath)",$destPath)))': $($_)"
                                                      return
                                                      }
                                            }

            }
}

                   
                #Write-Host "Deleting folder '$($sourcePath)'"
                #Remove-Item -Path "$($sourcePath)" -Recurse -Force -ErrorAction Stop

Phil,
Welcome to the forum. :wave:t4:

Hmmm … I’m unsure if I got it right…
You want to copy or move a folder structure from one folder to another, right? Why don’t you use robocopy? It is made for. Assuming I got your example right in the simplest case this should be all you need:

$dest = "G:\To Be Organised\Test"
$tempOutput = "G:\To Be Organised\_TestOutput"

robocopy $tempOutput $dest /e

If you want to move the folder structurte instead of copying it you can add the option /move.

I actually thought about RoboCopy, but I thought it was older tech. I shall give it a crack.

Essentially, your advice will replace this whole ‘move-item’ section:

Write-Host "Moving $($sourcePath) to $($destPath)"
                    ForEach($directory in $directoryList){
                    $directories = New-Item ($directory.FullName).Replace("$($sourcePath)",$destPath) -ItemType Directory -ea SilentlyContinue
                                             }
                    ForEach($file in $fileList){
                                                try {
                                                    Move-Item -Path $file.FullName -Destination ((Split-Path $file.FullName).Replace("$($sourcePath)",$destPath)) -Force -ErrorAction Stop
                                                    }
                                                catch{
                                                      Write-Warning "Unable to move '$($file.FullName)' to '$(((Split-Path $file.FullName).Replace("$($sourcePath)",$destPath)))': $($_)"
                                                      return
                                                      }
                                            }

With this:
robocopy $sourcePath $destPath /e /Move

AFAIK there’s nothing better (built in) than robocopy for moving files on Windows systems. It’s rock solid and well known for more than 20 years. And you should take a look at the several possible options to get the maximum out of it for you.

holy bonkers, it appears to be working!..

It ain’t pretty (each folder is creating it’s own robocopy process), but it’s working! Thanks heaps for your help.

So you might start a level higher then … play a little bit with it to get familiar with its abilities … it’s worth it.

Hopefully this helps some other pleb who was trying to follow this advice.

Powershell: Move all files from folders and subfolders into single folder - Stack Overflow

Powershell: Move Files & Folders In Directory Recursively to Another Directory · GitHub

I don’t know if you just got the wrong answer linked but again - if I got it right that’s a lot of overcomplicated code for a really simple task. :wink:

Sorry. I mean - I hope that whoever went down the rabbit hole on the wrong answer that I found on the internet (being those two links above), @olaf’s answer helps to set them back on course.

Ah … ok … I got it.

Thanks :+1:t4: :wink:

Not sure what options you chose for robocopy, but I always add /R:1 /W:1

That would be Retries of 1 and Wait to try again of 1 second.

The defaults are Retries of 1,000,000 and a wait of 30 seconds. Obviously if there is an issue copying a file, the defaults will pretty much stop your copy.

From “robocopy /?”

/R:n :: number of Retries on failed copies: default 1 million.
/W:n :: Wait time between retries: default is 30 seconds.

I always add logging as well and if logging, /NP so I dont get all the percent done stuff in the log file.