Methods for Displaying Progress During Large File Copy in PowerShell

Dec 03, 2025 · Programming · 9 views · 7.8

Keywords: PowerShell | progress display | file copy

Abstract: This article explores multiple technical approaches for showing progress bars when copying large files in PowerShell, focusing on custom functions using file streams and Write-Progress, with supplementary discussions on tools like BitsTransfer to enhance user experience and efficiency in file operations.

Introduction

In PowerShell, copying large files between servers often requires real-time progress feedback for monitoring operations. While the Copy-Item cmdlet lacks built-in progress display, custom methods can achieve this functionality.

Custom PowerShell Function for Progress Display

A core approach involves building a custom function using file streams and the Write-Progress cmdlet. This method reads and writes data in chunks, dynamically calculating and updating progress percentages. Here is a rewritten example based on stream operations:

function Copy-FileWithProgress {
    param (
        [string]$SourcePath,
        [string]$DestinationPath
    )
    $sourceFile = [System.IO.File]::OpenRead($SourcePath)
    $destFile = [System.IO.File]::OpenWrite($DestinationPath)
    Write-Progress -Activity "Copying File" -Status "$SourcePath -> $DestinationPath" -PercentComplete 0
    try {
        $buffer = New-Object byte[] 4096
        $totalBytesRead = 0
        $bytesRead = 0
        do {
            $bytesRead = $sourceFile.Read($buffer, 0, $buffer.Length)
            $destFile.Write($buffer, 0, $bytesRead)
            $totalBytesRead += $bytesRead
            if ($totalBytesRead % 1MB -eq 0) {
                $percentComplete = [math]::Round(($totalBytesRead / $sourceFile.Length) * 100)
                Write-Progress -Activity "Copying File" -Status "$SourcePath -> $DestinationPath" -PercentComplete $percentComplete
            }
        } while ($bytesRead -gt 0)
    }
    finally {
        $sourceFile.Dispose()
        $destFile.Dispose()
        Write-Progress -Activity "Copying File" -Status "Complete" -Completed
    }
}

This function uses a 4096-byte buffer and updates progress every megabyte read, minimizing overhead from frequent updates. Key aspects include efficient stream handling and exception management to ensure resource cleanup.

Using the BitsTransfer Module

As an alternative, the BitsTransfer module provides out-of-the-box support. Example code is as follows:

Import-Module BitsTransfer
Start-BitsTransfer -Source $Source -Destination $Destination -Description "Backup" -DisplayName "Backup"

This method includes built-in progress display and is compatible with most Windows systems, though it relies on an external module.

Other Supplementary Methods

Users can also consider command-line tools, such as cmd /c copy /z src dest, or the Shell Application COM object. These approaches offer simple implementations but may lack native PowerShell integration.

Conclusion

Custom functions provide maximum flexibility and control for complex scenarios, while BitsTransfer simplifies deployment. Choosing the appropriate method based on requirements can significantly improve user experience during large file copy operations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.