One of our clients recently wanted us to display a progress bar while copying files from one directory to another. This is a valid requirement when copying larger files.
Unfortunately, PowerShell’s Copy-Item cmdlet doesn’t display a progress bar by default. I recall the first time I attempted to copy a massive folder from a network share to my local drive. I sat there, staring at the blinking cursor, wondering if anything was happening at all! In those scenarios, a progress bar will definitely be helpful.
In this tutorial, I will show you step-by-step how to show progress when using Copy-Item in PowerShell, using different methods such as Write-Progress and RoboCopy.
Limitations of Copy-Item in PowerShell
In PowerShell, you can use the Copy-Item cmdlet to copy files from one directory to another, but it doesn’t show progress natively.
Basic Syntax
Copy-Item -Path "C:\Users\Bijay\Documents\Reports" -Destination "D:\Backups\Reports" -RecurseWhen I run this, there’s no indication of progress—just a blinking prompt until the command completes. For small files, this is fine. But for folders with hundreds or thousands of files, it’s not ideal.
Key Limitations:
| Feature | Copy-Item Default |
|---|---|
| Progress Bar | ❌ |
| File Count Info | ❌ |
| ETA | ❌ |
| Error Handling | Basic |
To see progress, you’ll need to use a custom approach or a different tool.
Check out Create a Folder with Today’s Date and Copy Files to it using PowerShell

Method 1: Using Write-Progress with Copy-Item (Custom Script)
After running into the limitations above, I started writing scripts that wrap Copy-Item in a way that displays progress using PowerShell’s Write-Progress cmdlet.
How Write-Progress Works
Write-Progress shows a progress bar in the console window, updating as your script runs. You can use it to display the percentage of files copied, the current file, and even estimated time remaining.
Step-by-Step Example
Let’s say I want to copy all files from C:\Data to E:\Backup\Data and show progress.
$source = "C:\Data"
$destination = "E:\Backup\Data"
# Get all files (recursively)
$files = Get-ChildItem -Path $source -Recurse -File
$total = $files.Count
$count = 0
foreach ($file in $files) {
$relativePath = $file.FullName.Substring($source.Length)
$targetPath = Join-Path $destination $relativePath
# Create target directory if it doesn't exist
$targetDir = Split-Path $targetPath
if (-not (Test-Path $targetDir)) {
New-Item -Path $targetDir -ItemType Directory -Force | Out-Null
}
# Copy the file
Copy-Item -Path $file.FullName -Destination $targetPath -Force
$count++
$percent = ($count / $total) * 100
Write-Progress -Activity "Copying files..." `
-Status "Copying $($file.Name) ($count of $total)" `
-PercentComplete $percent
}
Write-Progress -Activity "Copying files..." -Completed -Status "Done!"What’s Happening Here?
- Get-ChildItem collects all files to copy.
- The script loops through each file, copying it to the destination.
Write-Progressupdates after each file, showing:- The name of the file being copied
- How many files have been copied
- The percentage complete
Why I Like This
- It works for any folder, no matter how large.
- The progress bar is clear and updates in real time.
- You can easily add logging or error handling as needed.
When to Use
- Copying many files or large directories.
- When you need a simple, native PowerShell solution.
- When you want to customize the progress output.
Read PowerShell Copy-item Create Folder If Not Exist
Method 2: Using RoboCopy for Built-In Progress
If you’ve ever copied files on Windows, you’ve probably heard of RoboCopy. It’s a robust command-line tool built into Windows, and it displays a detailed progress bar by default.
Why Use RoboCopy?
- Built-in progress reporting (even for huge files)
- Handles retries, network interruptions, and long paths
- Great for copying large datasets
How to Use RoboCopy in PowerShell
You can call RoboCopy directly from PowerShell using the Start-Process or Invoke-Expression cmdlets.
Basic Example
Here is a basic example.
$source = "C:\Data"
$destination = "E:\Backup\Data"
Start-Process -NoNewWindow -Wait -FilePath "robocopy.exe" `
-ArgumentList "`"$source`" `"$destination`" /E /ETA /NFL /NDL"Key RoboCopy Switches
| Switch | Description |
|---|---|
| /E | Copy all subdirectories (including empty) |
| /ETA | Show estimated time of arrival |
| /NFL | No file list (reduces output noise) |
| /NDL | No directory list |
RoboCopy’s console output includes a live progress bar, file count, and ETA. It’s my go-to for heavy-duty copy jobs.
Advanced: Capture RoboCopy Output
If you want to capture RoboCopy’s output and display it in your PowerShell console, you can do:
$robocopyCmd = "robocopy `"$source`" `"$destination`" /E /ETA"
Invoke-Expression $robocopyCmdOr, for even more control, parse its output and update a custom progress bar.
Check out Copy and Rename Files in PowerShell
Method 3: Monitoring Progress for Large Single Files
If you’re copying a single large file (like a video or backup image), neither Copy-Item nor Write-Progress will show byte-level progress. Here’s how I handle this:
Using System.IO for Byte-Level Progress
You can use .NET’s System.IO.FileStream to copy a file chunk by chunk and update progress based on bytes copied.
Example Script
$source = "C:\BigFiles\movie.mp4"
$destination = "E:\Backup\movie.mp4"
$bufferSize = 4MB
$sourceStream = [System.IO.File]::OpenRead($source)
$destStream = [System.IO.File]::Create($destination)
$totalBytes = $sourceStream.Length
$bytesCopied = 0
$buffer = New-Object byte[] $bufferSize
while (($read = $sourceStream.Read($buffer, 0, $bufferSize)) -gt 0) {
$destStream.Write($buffer, 0, $read)
$bytesCopied += $read
$percent = ($bytesCopied / $totalBytes) * 100
Write-Progress -Activity "Copying large file..." `
-Status "$([math]::Round($percent,2))% complete" `
-PercentComplete $percent
}
$sourceStream.Close()
$destStream.Close()
Write-Progress -Activity "Copying large file..." -Completed -Status "Done!"When to Use
- Copying very large files (multi-GB)
- When you need real-time progress in PowerShell
- For advanced automation scripts
Conclusion
In this tutorial, I explained how to show a progress bar while copying files from one folder to another using PowerShell. Over the years, I’ve relied on both custom Write-Progress scripts and RoboCopy for different scenarios.
If you’re working with lots of files or need advanced features, RoboCopy is hard to beat. For smaller copy jobs or when you want to stay 100% in PowerShell, the custom progress script is perfect.
Try out the methods above and see which one works best for your requirements. If you have any questions or want to share your own tips, drop a comment below—I’d love to hear from you.
I hope you found this tutorial helpful. If you have any questions or suggestions, feel free to leave them in the comments below!
You may also like the following tutorials:
- Copy Files from One Folder to Another in PowerShell
- List Directories and Files in PowerShell
- Create Multiple Folders in PowerShell
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.