Created
November 19, 2022 08:35
-
-
Save rpratama123/b394561290e2e31bbe1364c8087ca964 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Copy-WithProgress { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory = $true)] | |
[string] $Source | |
, [Parameter(Mandatory = $true)] | |
[string] $Destination | |
, [int] $Gap = 200 | |
, [int] $ReportGap = 2000 | |
) | |
# Define regular expression that will gather number of bytes copied | |
$RegexBytes = '(?<=\s+)\d+(?=\s+)'; | |
#region Robocopy params | |
# MIR = Mirror mode | |
# NP = Don't show progress percentage in log | |
# NC = Don't log file classes (existing, new file, etc.) | |
# BYTES = Show file sizes in bytes | |
# NJH = Do not display robocopy job header (JH) | |
# NJS = Do not display robocopy job summary (JS) | |
# TEE = Display log in stdout AND in target log file | |
$CommonRobocopyParams = '/MIR /NP /NDL /NC /BYTES /NJH /NJS'; | |
#endregion Robocopy params | |
#region Robocopy Staging | |
Write-Verbose -Message 'Analyzing robocopy job ...'; | |
$StagingLogPath = '{0}\temp\{1} robocopy staging.log' -f $env:windir, (Get-Date -Format 'yyyy-MM-dd HH-mm-ss'); | |
$StagingArgumentList = '"{0}" "{1}" /LOG:"{2}" /L {3}' -f $Source, $Destination, $StagingLogPath, $CommonRobocopyParams; | |
Write-Verbose -Message ('Staging arguments: {0}' -f $StagingArgumentList); | |
Start-Process -Wait -FilePath robocopy.exe -ArgumentList $StagingArgumentList -NoNewWindow; | |
# Get the total number of files that will be copied | |
$StagingContent = Get-Content -Path $StagingLogPath; | |
$TotalFileCount = $StagingContent.Count - 1; | |
# Get the total number of bytes to be copied | |
[RegEx]::Matches(($StagingContent -join "`n"), $RegexBytes) | % { $BytesTotal = 0; } { $BytesTotal += $_.Value; }; | |
Write-Verbose -Message ('Total bytes to be copied: {0}' -f $BytesTotal); | |
#endregion Robocopy Staging | |
#region Start Robocopy | |
# Begin the robocopy process | |
$RobocopyLogPath = '{0}\temp\{1} robocopy.log' -f $env:windir, (Get-Date -Format 'yyyy-MM-dd HH-mm-ss'); | |
$ArgumentList = '"{0}" "{1}" /LOG:"{2}" /ipg:{3} {4}' -f $Source, $Destination, $RobocopyLogPath, $Gap, $CommonRobocopyParams; | |
Write-Verbose -Message ('Beginning the robocopy process with arguments: {0}' -f $ArgumentList); | |
$Robocopy = Start-Process -FilePath robocopy.exe -ArgumentList $ArgumentList -Verbose -PassThru -NoNewWindow; | |
Start-Sleep -Milliseconds 100; | |
#endregion Start Robocopy | |
#region Progress bar loop | |
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; }; | |
$CopiedFileCount = $LogContent.Count - 1; | |
Write-Verbose -Message ('Bytes copied: {0}' -f $BytesCopied); | |
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} files; Copied {2} of {3} bytes" -f $CopiedFileCount, $TotalFileCount, $BytesCopied, $BytesTotal) -PercentComplete $Percentage | |
} | |
#endregion Progress loop | |
#region Function output | |
[PSCustomObject]@{ | |
BytesCopied = $BytesCopied; | |
FilesCopied = $CopiedFileCount; | |
}; | |
#endregion Function output | |
} | |
# 1. TESTING: Generate a random, unique source directory, with some test files in it | |
$TestSource = '{0}\{1}' -f $env:temp, [Guid]::NewGuid().ToString(); | |
$null = mkdir -Path $TestSource; | |
# 1a. TESTING: Create some test source files | |
1..20 | % -Process { Set-Content -Path $TestSource\$_.txt -Value ('A'*(Get-Random -Minimum 10 -Maximum 2100)); }; | |
# 2. TESTING: Create a random, unique target directory | |
$TestTarget = '{0}\{1}' -f $env:temp, [Guid]::NewGuid().ToString(); | |
$null = mkdir -Path $TestTarget; | |
# 3. Call the Copy-WithProgress function | |
Copy-WithProgress -Source $TestSource -Destination $TestTarget -Verbose; | |
# 4. Add some new files to the source directory | |
21..40 | % -Process { Set-Content -Path $TestSource\$_.txt -Value ('A'*(Get-Random -Minimum 950 -Maximum 1400)); }; | |
# 5. Call the Copy-WithProgress function (again) | |
Copy-WithProgress -Source $TestSource -Destination $TestTarget -Verbose; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment