PowerShell Robocopy: Advanced File Copy Options Explained

PowerShell Robocopy: Advanced File Copy Options Explained

PowerShell Tips Editor 3 min read
PowerShell Robocopy: Advanced File Copy Options Explained

When copying hundreds of gigabytes over a flaky VPN or network link, Copy-Item fails without retry and leaves you with an incomplete transfer. PowerShell Robocopy is the professional file copy tool built into Windows that resumes interrupted transfers, copies with multiple threads, and logs everything to a file. This post covers the Robocopy options that make large-scale file operations reliable.

Quick Answer / TL;DR

Run robocopy $source $dest /MIR /R:3 /W:5 /MT:8 /LOG:C:\Logs\robocopy.log for a mirrored copy with 3 retries, 5-second wait, 8 threads, and a log file.

Basic Robocopy Syntax in PowerShell

Robocopy is called as a native executable from PowerShell. Unlike Copy-Item, it takes positional source and destination arguments (not parameters). Wrap paths with spaces in double quotes. Robocopy exit code 0 means no files were copied; exit code 1 means files were copied successfully — neither is an error.

# Basic directory copy — copies all files, preserves structure
robocopy C:\Source C:\Destination

# Copy with specific file pattern
robocopy C:\Logs \\server\backup\logs *.log

# Check exit code
$exitCode = $LASTEXITCODE
if ($exitCode -le 7) {
    Write-Host "Robocopy succeeded (exit code $exitCode)"
} else {
    Write-Warning "Robocopy reported errors (exit code $exitCode)"
}

Retry and Wait on Failure

/R:n sets the number of retries on failed copies; /W:n sets the wait time in seconds between retries. The default is /R:1000000 /W:30 — an aggressive default that is rarely what you want in scripts. Set explicit, reasonable values. /R:3 /W:5 is appropriate for most scenarios.

# Retry 3 times, wait 5 seconds between retries
robocopy C:\Deploy \\server\deploy /E /R:3 /W:5

# For unstable network links: more retries, longer wait
robocopy C:\Backup \\remoteserver\data /MIR /R:10 /W:30 /LOG:C:\Logs\copy.log

Multithreaded Copies with /MT

/MT:n runs Robocopy with n parallel threads (1–128). The default is 8. Increasing threads speeds up copies of many small files dramatically but provides minimal benefit for a few very large files. Do not combine /MT with /IPG (inter-packet gap) — they are incompatible. Use /UNILOG instead of /LOG when using /MT to prevent log file corruption from concurrent writes.

# 16-thread copy for many small files
robocopy C:\WebApp \\webserver\wwwroot /E /MT:16 /R:3 /W:5 /UNILOG:C:\Logs\deploy.log

# Single thread for large files (fewer threads reduce memory overhead)
robocopy C:\VMs \\storageserver\vms /E /MT:2 /R:5 /W:10

Exclude Files and Folders

Use /XF (exclude files by name/wildcard) and /XD (exclude directories) to skip files you do not want copied. This is essential for excluding logs, temp files, and cache directories from deployment or backup operations.

# Exclude temp and log files
robocopy C:\App \\server\backup /E /XF *.tmp *.log /XD temp cache .git

# Exclude multiple specific directories
robocopy C:\Repo \\nas\backup /E `
    /XD '.git' 'node_modules' 'dist' 'bin' 'obj' `
    /XF '*.suo' '*.user' '*.log' `
    /R:2 /W:3

Log Output to File

/LOG:path writes Robocopy output to a log file (overwrites existing). /LOG+:path appends to an existing log. /UNILOG:path writes Unicode log, required when using /MT to prevent threading corruption. The log captures every file copied, skipped, or failed, which is valuable for auditing large migrations.

# Log to file with timestamp in name
$logFile = "C:\Logs\robocopy_$(Get-Date -Format 'yyyyMMdd_HHmm').log"
robocopy C:\Source \\server\dest /E /R:3 /W:5 /UNILOG:$logFile /TEE

# /TEE shows output in console AND writes to log
# Parse log after completion
$summary = Get-Content $logFile | Select-String 'Files\s+:' | Select-Object -Last 1
Write-Host "Copy summary: $summary"

Mirror vs Copy Mode

/E copies all subdirectories including empty ones, but does not delete files at the destination that no longer exist at the source. /MIR (mirror) copies everything AND deletes files at the destination that are not in the source — use this for true synchronization. Be careful with /MIR on backups — it removes old files from the backup destination.

# /E: copy only, no deletion at destination (safe for backups)
robocopy C:\Config \\server\config_backup /E /R:3 /W:5

# /MIR: exact mirror — deletes files at destination not in source (use with care)
robocopy C:\WebRoot \\webserver\wwwroot /MIR /R:3 /W:5

# /MIR with exclusion to protect specific destination files
robocopy C:\WebRoot \\webserver\wwwroot /MIR /XF web.config /R:3 /W:5

Common Errors and Fixes

  • Exit code 1 from Robocopy means success with files copied — not an error. Robocopy uses exit codes 0–7 to indicate success with various conditions (nothing copied, files copied, extra files found). Exit codes 8 and above indicate actual errors. In PowerShell, $LASTEXITCODE -gt 7 is the correct error check. Do not use $? — it reads the PowerShell success/failure of launching the process, not Robocopy’s outcome.
  • /MT and /LOG conflict — use /UNILOG for log with multithreading. Using /LOG with /MT causes multiple threads to write to the log simultaneously, corrupting the log file. Replace /LOG:path with /UNILOG:path when using /MT. /UNILOG is thread-safe and writes Unicode output.

Related Cmdlets / See Also

Wrapping Up

Robocopy is the right tool whenever Copy-Item is too fragile for the job. Set explicit /R and /W values, use /MT for many small files, log with /UNILOG when multithreading, and check $LASTEXITCODE -le 7 for success. For deployment synchronization use /MIR carefully — it deletes as well as copies.

Send-Item -To