When dealing with file synchronization tasks in Windows, robocopy is often the tool of choice for its robustness and flexibility. However, one particular pain point developers encounter is excluding files based on directory names anywhere in their path structure.
c:\foo\bar\a.txt ← should be excluded
c:\bar\c.txt ← should be excluded
d:\baz\bar\flub\d.txt ← should be excluded
c:\foo\barf\b.txt ← should NOT be excluded
The intuitive approaches don't work as expected:
robocopy source dest /XD \bar\ ← fails
robocopy source dest /XD *\bar\* ← fails
robocopy source dest /XD *^\bar^\* ← fails
The fundamental issue is that robocopy's /XD parameter doesn't support wildcards for partial path matching. It only works for complete directory names at specific levels.
To achieve proper wildcard-like directory exclusion, we need to combine several techniques:
robocopy source destination /XD bar /XD *\bar /XD *\bar\*
This three-part exclusion handles all cases:
/XD bar
- catches root-level "bar" directories/XD *\bar
- catches "bar" directories one level deep/XD *\bar\*
- catches "bar" directories at any deeper level
Here's a complete robocopy command with proper exclusions and common parameters:
robocopy C:\source D:\destination /MIR /ZB /R:2 /W:3 /TEE /V /XD bar /XD *\bar /XD *\bar\* /LOG+:C:\logs\robocopy.log
For more complex scenarios, you can combine robocopy with PowerShell to generate exclusion lists:
$excludeFiles = Get-ChildItem -Path C:\source -Recurse -File |
Where-Object { $_.FullName -match '\\bar\\' } |
Select-Object -ExpandProperty FullName
robocopy C:\source D:\destination /MIR /XF $excludeFiles
- Robocopy versions prior to Windows 7 might not handle these patterns correctly
- Very long path names (> 260 chars) may cause issues with pattern matching
- The exclusion patterns are case-insensitive by default
When working with robocopy's exclusion parameters, I encountered a specific scenario where I needed to exclude any file whose full path contains a directory named "bar" at any level. The standard /XD
parameter wasn't cooperating with wildcards the way I expected.
Here are the patterns I initially tried (all rejected by robocopy):
robocopy source dest /XD \\bar\\
robocopy source dest /XD *\\bar\\*
robocopy source dest /XD *^\\bar^\\*
After extensive testing, I discovered robocopy actually treats each /XD
parameter as a complete path component pattern. The solution is to specify multiple exclusion patterns:
robocopy source dest /XD *\bar bar *\bar\*
Here's a complete batch file example that demonstrates proper exclusion of any path containing "temp" folders:
@echo off
set SOURCE=C:\projects
set DEST=D:\backup
set EXCLUDE=temp
robocopy %SOURCE% %DEST% /MIR /XD *\%EXCLUDE% %EXCLUDE% *\%EXCLUDE%\* /R:1 /W:1 /LOG:C:\robocopy.log
- Robocopy matches directory names case-insensitively
- The order of exclusion patterns matters - more specific patterns should come first
- Backslashes must be single (not escaped) in the patterns
For more complex exclusion needs, consider generating the exclusion list dynamically:
@echo off
setlocal enabledelayedexpansion
set EXCLUDE_DIRS=temp cache logs
set XD_PARAMS=
for %%d in (%EXCLUDE_DIRS%) do (
set XD_PARAMS=!XD_PARAMS! *\%%d %%d *\%%d\*
)
robocopy C:\source D:\dest /MIR /XD %XD_PARAMS%