Exclude list in PowerShell Copy-Item does not appear to be working

I have the following snippet of PowerShell script:

$source = 'd:\t1\*'
$dest = 'd:\t2'
$exclude = @('*.pdb','*.config')
Copy-Item $source $dest -Recurse -Force -Exclude $exclude

Which works to copy all files and folders from t1 to t2, but it only excludes the exclude list in the "root"/"first-level" folder and not in sub-folders.

How do I make it exclude the exclude list in all folders?


Solution 1:

I think the best way is to use Get-ChildItem and pipe in the Copy-Item command.

I found that this worked:

$source = 'd:\t1'
$dest = 'd:\t2'
$exclude = @('*.pdb','*.config')
Get-ChildItem $source -Recurse -Exclude $exclude | Copy-Item -Destination {Join-Path $dest $_.FullName.Substring($source.length)}

Basically, what is happening here is that you're going through the valid files one by one, then copying them to the new path. The 'Join-Path' statement at the end is so that the directories are also kept when copying over the files. That part takes the destination directory and joins it with the directory after the source path.

I got the idea from here, and then modified it a bit to make it work for this example.

I hope it works!

Solution 2:

I had this problem, too, and spent 20 minutes with applying the solutions here, but kept having problems.
So I chose to use robocopy - OK, it's not powershell, but should be available everywhere where powershell runs.

And it worked right out of the box:

robocopy $source $dest /S /XF <file patterns to exclude> /XD <directory patterns to exclude>

e.g.

robocopy $source $dest /S /XF *.csproj /XD obj Properties Controllers Models

Plus, it has tons of features, like resumable copy. Docs here.