I would like some help implementing a progress function in my robocopy backup script.
I have the following code:
$drv = D:\
$dst = B:\
$XF = "03. Proxy", "`$Recycle.Bin", "System Volume Information"
$XA = ".avi", "desktop.ini", ".ico"
$Verify_ssdOrigem_Files = Get-ChildItem -Path $drv -Recurse | Where-Object { $_.PSIsContainer -eq $false -and $_.Extension -notin $XA -and $_.Name -notin $XF} # Get the Source SSD to use in the $Compare variable
$Verify_ssdBackup_Files = Get-ChildItem -Path $dst -Recurse | Where-Object { $_.PSIsContainer -eq $false -and $_.Extension -notin $XA -and $_.Name -notin $XF} # Get the Backup SSD to use in the $Compare variable
$Compare = (Compare-Object -ReferenceObject $Verify_ssdOrigem_Files -DifferenceObject $Verify_ssdBackup_Files -Property Name, Length |
Where-Object { $_.SideIndicator -eq '<=' } |
Measure-Object).Count # This code checks which identical files exist in the source folder and destination folder, this way the count will always be correct, even if the copy process is paused and started again.
Function Get-RobocopyProgress {
param(
[Parameter(Mandatory,ValueFromPipeline)]
$InputObject
)
begin {
[string]$file = " "
[double]$percent = 0
[double]$size = $Null
[double]$count = $Compare -1
[double]$filesLeft = $count
[double]$number = 0
}
process {
$Host.PrivateData.ProgressBackgroundColor='Green'
$Host.PrivateData.ProgressForegroundColor='Black'
$data = $InputObject -split '\x09'
# The "-and" added to the bottom line is used so that files and folders that should be ignored in the copy are not considered in the total count of files to be copied
If (![String]::IsNullOrEmpty("$($data[4])") -and ($data[4] -notin $XA) -and ($data[4] -notin $XF)){
$file = $data[4] -replace '.+\\(?=(?:.(?!\\))+$)'
$filesLeft--
$number++
}
If(![String]::IsNullOrEmpty("$($data[0])")){
# Check if $data[0] is a numeric value before trying to convert
if ($data[0] -match '^[\d.]+$') {
$percent = ($data[0] -replace '%') -replace '\s'
}
else {
$percent = 0
}
}
If(![String]::IsNullOrEmpty("$($data[3])")){
$size = $data[3]
}
[String]$sizeString = switch ($size) {
{$_ -gt 1TB -and $_ -lt 1024TB} {
"$("{0:n2}" -f ($size / 1TB) + " TB")"
}
{$_ -gt 1GB -and $_ -lt 1024GB} {
"$("{0:n2}" -f ($size / 1GB) + " GB")"
}
{$_ -gt 1MB -and $_ -lt 1024MB} {
"$("{0:n2}" -f ($size / 1MB) + " MB")"
}
{$_ -ge 1KB -and $_ -lt 1024KB} {
"$("{0:n2}" -f ($size / 1KB) + " KB")"
}
{$_ -lt 1KB} {
"$size B"
}
}
Write-Progress -Activity " Currently copying: ..\$file"`
-CurrentOperation "copying: $(($number).ToString()) of $(($count).ToString()) Copied: $(if($number -le 0){($number).ToString()}else{($number).ToString()}) / $(($count).ToString()) Remaining Files: $(($filesLeft).ToString())"`
-Status "Size: $sizeString Complete: $percent%"`
-PercentComplete $percent
}
}
robocopy "$($source = $drv;$source)" "$($destination = "$dst";$destination)" /e /NJH /NDL /NC /BYTES /MT:32 /zb /copyall /A-:SH /xd $XF /xf $XA /log:"$dst\_Backup Logs\$filedate-robocopylog.txt" /tee | Get-RobocopyProgress
I'm trying to make my Backup script present a correct preview of how many files still need to be copied until the backup is complete, this helps me get an idea of how long it will take until the Backup is finished.
The logic I'm using is to count how many files there are on the source device that don't exist on the backup device.
I followed this logic because in theory this way the count will always be correct, even if the script is closed in the middle of execution and run again immediately afterwards, because the files will always be counted before starting the backup.
This logic can be observed in the $Compare variable.
The issue is that for some reason the counting is not happening correctly, the impression I have is that in the comparison some types of files that robocopy copies are not being taken into account, probably hidden files or files with system properties, therefore, the counting is always ending in negative numbers.
What made me think about this was that by adding Desktop.ini to the $XA variable I get results that are closer to being correct.
Any ideas on how I can always have a correct count of how many files will be copied by robocopy?