Custom RoboCopy Progress Bar in PowerShell

后端 未结 7 969
夕颜
夕颜 2020-11-28 03:51

I\'m interested in a PowerShell script that copies a large amount of files from a server daily and I\'m interested in implementing a in-console progress bar like

相关标签:
7条回答
  • 2020-11-28 04:43

    Do you absolutely have to use robocopy?

    If not you could call the code in this thread for each file: Progress during large file copy (Copy-Item & Write-Progress?)

    Alternatively use the /L switch of robocopy as called from powershell to get list of files robocopy would have copied and use a for-each loop to run each file through that copy function.

    You could even nest write-progress commands so you can report "file x of y - XX% complete"

    Something like this should work, needs a little work for subdirectories (I suspect more than just adding -recurse to the gci command) but will put you inthe right direction.

    NOTE: I'm writing this on a phone, the code is untested as yet...

    function Copy-File {
    param( [string]$from, [string]$to)
    $ffile = [io.file]::OpenRead($from)
    $tofile = [io.file]::OpenWrite($to)
    Write-Progress `
        -Activity ("Copying file " + $filecount + " of " + $files.count) `
        -status ($from.Split("\")|select -last 1) `
        -PercentComplete 0
    try {
        $sw = [System.Diagnostics.Stopwatch]::StartNew();
        [byte[]]$buff = new-object byte[] 65536
        [long]$total = [long]$count = 0
        do {
            $count = $ffile.Read($buff, 0, $buff.Length)
            $tofile.Write($buff, 0, $count)
            $total += $count
            if ($total % 1mb -eq 0) {
                if([int]($total/$ffile.Length* 100) -gt 0)`
                    {[int]$secsleft = ([int]$sw.Elapsed.Seconds/([int]($total/$ffile.Length* 100))*100)
                    } else {
                    [int]$secsleft = 0};
                Write-Progress `
                    -Activity ([string]([int]($total/$ffile.Length* 100)) + "% Copying file")`
                    -status ($from.Split("\")|select -last 1) `
                    -PercentComplete ([int]($total/$ffile.Length* 100))`
                    -SecondsRemaining $secsleft;
            }
        } while ($count -gt 0)
    $sw.Stop();
    $sw.Reset();
    }
    finally {
        $ffile.Close()
        $tofile.Close()
        }
    }
    
    $srcdir = "C:\Source;
    $destdir = "C:\Dest";
    [int]$filecount = 0;
    $files = (Get-ChildItem $SrcDir | where-object {-not ($_.PSIsContainer)});
    $files|foreach($_){
    $filecount++
    if ([system.io.file]::Exists($destdir+$_.name)){
                    [system.io.file]::Delete($destdir+$_.name)}
                    Copy-File -from $_.fullname -to ($destdir+$_.name)
    };
    

    Personally I use this code for small copies to a USB stick but I use robocopy in a powershell script for PC backups.

    0 讨论(0)
提交回复
热议问题