I am trying to create a custom Robocopy status GUI in powershell, here is my basic code.
$script:Robocopy = Start-Process -FilePath robocopy.exe -ArgumentList $ArgumentList -Verbose -PassThru -NoNewWindow;
$RCStatus = Start-Job -Name RCLOOP -ArgumentList $Robocopy, $ReportGap, $RobocopyLogPath, $RegexBytes, $RobocopyFileProgress, $RobocopyMBProgress, $RobocopyGBProgress, $RobocopyPcntProgress, $RobocopySpeed {
param ($Robocopy, $ReportGap, $RobocopyLogPath, $RegexBytes, $RobocopyFileProgress, $RobocopyMBProgress, $RobocopyGBProgress, $RobocopyPcntProgress, $RobocopySpeed)
$iterations = 0
[array]$avgSpeedarray = @()
while (!$Robocopy.HasExited) {
Start-Sleep -Milliseconds $ReportGap;
$BytesCopied = 0;
$LogContent = Get-Content -Path $RobocopyLogPath;
$BytesCopied = [Regex]::Matches($LogContent, $RegexBytes) | ForEach-Object -Process { $BytesCopied += $_.Value; } -End { $BytesCopied; };
$global:MBCopied = ($BytesCopied / 1048576)
$global:GBCopied = ($BytesCopied / 1073741824)
$script:CopiedFileCount = $LogContent.Count - 1;
$iterations++
if ($iterations % 2 -eq 1) {
$M = $MBCopied
}
else {
$B = $MBCopied
$script:TSpeed = ($B - $M) * 8
$avgSpeedarray += $script:TSpeed
if ($avgSpeedarray.count -gt 4) {
$script:avgSpeed = (($avgSpeedarray[-1..-10] | Measure-Object -sum).sum) / 10
if ($avgSpeedarray.count -gt 19) {
$keep = $avgSpeedarray[-1..-9]
$avgSpeedarray = @()
$avgSpeedarray += $keep
}
}
}
if ($iterations % 20 -eq 0) {
$keepAwake
}
Write-Verbose -Message ('MB copied: {0}' -f $MBCopied);
Write-Verbose -Message ('Files copied: {0}' -f $LogContent.Count);
$Percentage = 0;
if ($BytesCopied -gt 0) {
$Percentage = (($BytesCopied / $BytesTotal) * 100)
}
#Write-Progress -Activity Robocopy -Status ("Copied {0} of {1} | {2}GB of {3}GB | {4}MB of {5}MB | {6}% Complete (Average: {7}Mbps)" -f $CopiedFileCount, $TotalFileCount, [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2), [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal), [Math]::Round($Percentage, 2), [Math]::Round($script:avgSpeed,2)) -PercentComplete $Percentage
$RobocopyFileProgress.Text = ("Files: {0} of {1}" -f $CopiedFileCount, $TotalFileCount)
$RobocopyMBProgress.Text = ("Data: {0}MB of {1}MB" -f [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal, 2))
$RobocopyGBProgress.Text = ("Data: {0}GB of {1}GB" -f [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2))
$RobocopyPcntProgress.Text = ("Percentage: {0}%" -f [Math]::Round($Percentage, 2))
$RobocopySpeed.text = ("Speed: {0}Mbps" -f [Math]::Round($script:avgSpeed, 2))
}
}
$RobocopyProgressGUI.Show()
#endregion Progress loop
Register-ObjectEvent -InputObject $script:Robocopy -EventName OutputDataReceived -SourceIdentifier 'RobocopyStatus' -Action {
$RobocopyFileProgress.Text = ("Files: {0} of {1}" -f $CopiedFileCount, $TotalFileCount)
$RobocopyMBProgress.Text = ("Data: {0}MB of {1}MB" -f [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal, 2))
$RobocopyGBProgress.Text = ("Data: {0}GB of {1}GB" -f [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2))
$RobocopyPcntProgress.Text = ("Percentage: {0}%" -f [Math]::Round($Percentage, 2))
$RobocopySpeed.text = ("Speed: {0}Mbps" -f [Math]::Round($script:avgSpeed, 2))
}
One of my issues is that my form just opens and closes without any script telling it to close, another is all the code above outputs is the information about the Job, not what the job is outputting.
I know my code is very verbose, it was part of the troubleshooting process, I know C# is a better option but I am trying to achieve it in powershell as I am not very good in C#. Any Help or suggestion would be amazing. If you need any other code from my program that I missed in this, please let me know and I will provide it