Robocopy powershell script with progress bar (and/or percentage) for both current file that is copying and the total copy job

Robocopy powershell script with progress bar (and/or percentage) for both current file that is copying and the total copy job

I had found and tried script from https://www.experts-exchange.com/questions/29046366/Robocopy-Script-with-progress-bar-or-percentage-progress.html - but got errors which I posted on that question but had no response

Can anyone help please

Thanks
Darren RoseAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CastroCEO Faru Bonon IT - EE Solution ExpertCommented:
Have you tried this?

https://gallery.technet.microsoft.com/scriptcenter/Copy-Files-from-folderA-to-29710ef9

This is my script if you have any issue/requirement we can see it.

jose
Darren RoseAuthor Commented:
Hi Jose

Just tried that, and not really sure how it covers anything I asked for - as yes it copies files from A to B - but it doesn't show progress for the overall operation or that I can see really for each file, just a load of scrolling copy operations
Jose Gabriel Ortega CastroCEO Faru Bonon IT - EE Solution ExpertCommented:
it doens't have a progress bar.
Because it just copies everything from A to B, recursively by default.
to make a progress bar I would need to do the job twice (one to get the total number) and another to do the progress.
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

Darren RoseAuthor Commented:
@Jose

Okay fair enough, but my question specifically requested a progress bar both in the question title and the question itself, so thanks for replying but if I wanted a solution without progress bar then I would have said
Darren RoseAuthor Commented:
this seems to work well to show progress of the whole copy job - if it could be amended to show progress bar for each file as well (as handy for larger files to know progress per file)

p.s. though it does seem quite slow to do the copy

https://github.com/KurtDeGreeff/PlayPowershell/blob/master/RoboCopy-WithProgress.ps1
dsuyemotoCommented:
Here is a modified version I created from the comments on this post in SO

function Copy-WithProgressBars {
    [CmdletBinding()]
    param (
          [Parameter(Mandatory = $true)]
            [string] $Source
        , [Parameter(Mandatory = $true)]
            [string] $Destination
    )
    
$totalbytes = 0
$currentbytes = 0
$currentprocessedbytes = 0
$processedbytes = 0

$sourcefiles = Get-ChildItem -Path $Source
$sourcefiles | % { $totalbytes += $_.Length }     
#Write-Host "Total Bytes: $totalbytes"

$sourcefiles |
    % {              
        RoboCopy $Source $Destination $_.Name /is /it /ndl /njh /njs /bytes /tee | % {
            $data = $_.Split([char]9); 
            if("$($data[3])" -ne "") { $currentbytes = [int]$data[3] };
            if("$($data[4])" -ne "") { $file = "$($data[4])"} ;
            [decimal]$currentpercent = [math]::Round([decimal]($data[0] -replace "%",""),1)
            Write-Progress "Percentage $currentpercent%" -Activity "Current File:" -CurrentOperation "$($file)" -ErrorAction SilentlyContinue -PercentComplete $currentpercent                  
            [int]$currentprocessedbytes = [math]::Round($currentbytes * ($currentpercent / 100))
            [decimal]$processedpercent = [math]::Round((($processedbytes + $currentprocessedbytes) / $totalbytes) * 100,1)
            Write-Progress -id 1 "Percentage $processedpercent%" -Activity "All Files:" -ErrorAction SilentlyContinue -PercentComplete $processedpercent
            }
        $processedbytes += $currentprocessedbytes
        $srcDoc = "{0}\{1}" -f $Source,$_.Source
        $dstDoc = "{0}\{1}" -f $Destination,$_.Source
    }
}

Open in new window

FYI, the reason why the script "RoboCopy-WithProgress.ps1" runs so slow is that they intentionally added delays through the gap parameter so that you could more easily see the file progress for short files.
Darren RoseAuthor Commented:
Thanks for reply - think I am missing something as this just shows the same as a script I had posted e.g. it is only showing total progress, it is not showing for BOTH total progress and each individual file as I asked?

Yes that make sense as to why they had added gap parameter - is this why I don't see per file progress with you solution?
dsuyemotoCommented:
There are two write-progress lines, one for the current file, the other for the total files progress:

Write-Progress "Percentage $currentpercent%" -Activity "Current File:" -CurrentOperation "$($file)" -ErrorAction SilentlyContinue -PercentComplete $currentpercent                  

Write-Progress -id 1 "Percentage $processedpercent%" -Activity "All Files:" -ErrorAction SilentlyContinue -PercentComplete $processedpercent

The "-id 1" on the second write-progress allows an additional progress bar below the original one.
Darren RoseAuthor Commented:
something is not quite right with it then as it runs too quickly and doesn't actually copy most of the files, just seems to do first level and some folders, but not contents of sub folders?
dsuyemotoCommented:
With recursion added:

function Copy-WithProgressBars {
    [CmdletBinding()]
    param (
          [Parameter(Mandatory = $true)]
            [string] $Source
        , [Parameter(Mandatory = $true)]
            [string] $Destination
    )
    
$totalbytes = 0
$currentbytes = 0
$currentprocessedbytes = 0
$processedbytes = 0
$lastbytes = 0

Get-ChildItem -Path $Source -Recurse -File | % { $totalbytes += $_.Length }     
#Write-Host "Total Bytes: $totalbytes"

RoboCopy $Source $Destination /s /is /it /ndl /njh /njs /bytes | % {
    $data = $_.Split([char]9); 
    if("$($data[4])" -ne "") { $file = "$($data[4])"; $processedbytes += $lastbytes } ;
    if("$($data[3])" -ne "") { $currentbytes = [int]$data[3]; $lastbytes = $currentbytes };           
    [decimal]$currentpercent = [math]::Round([decimal]($data[0] -replace "%",""),1)
    Write-Progress "Percentage $currentpercent%" -Activity "Current File:" -CurrentOperation "$($file)" -ErrorAction SilentlyContinue -PercentComplete $currentpercent                  
    [int]$currentprocessedbytes = [math]::Round($currentbytes * ($currentpercent / 100))
    [decimal]$processedpercent = [math]::Round((($processedbytes + $currentprocessedbytes) / $totalbytes) * 100,1)
    Write-Progress -id 1 "Percentage $processedpercent%" -Activity "All Files:" -ErrorAction SilentlyContinue -PercentComplete $processedpercent
    $lastbytes = $currentprocessedbytes
    }                  
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Darren RoseAuthor Commented:
Thank you - that works perfectly!!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.