MicrosoftDocs / PowerShell-Docs

The official PowerShell documentation sources
https://learn.microsoft.com/powershell
Other
1.96k stars 1.56k forks source link

Copy-Item -Exclude Parameter DOES filter on child paths #10295

Closed elliott-beach closed 11 months ago

elliott-beach commented 1 year ago

Prerequisites

Links

Summary

"Since this parameter only filters on the paths resolved for the Path parameter, it doesn't filter any items discovered when recursing through child folders with the Recurse parameter."

Not true. I find that the -Exclude parameter also filters items discovered when recursing through child folders.

Details

Tested on version 5.1.19041.3031

PS C:\Users\ebeach\test\PowershellExcludeBehavior> tree /F Test1
C:\USERS\EBEACH\TEST\POWERSHELLEXCLUDEBEHAVIOR\TEST1
│   FizzBuzz.txt
│   Foo.txt
│
└───Test2
        FizzBuzz.txt
        Foo2.txt

PS C:\Users\ebeach\test\PowershellExcludeBehavior> tree /F Test3
C:\USERS\EBEACH\TEST\POWERSHELLEXCLUDEBEHAVIOR\TEST3
No subfolders exist

PS C:\Users\ebeach\test\PowershellExcludeBehavior> Copy-Item Test1/* Test3 -Recurse -Exclude FizzBuzz.txt
PS C:\Users\ebeach\test\PowershellExcludeBehavior> tree /F Test3
C:\USERS\EBEACH\TEST\POWERSHELLEXCLUDEBEHAVIOR\TEST3
│   Foo.txt
│
└───Test2
        Foo2.txt

Suggested Fix

No response

sdwheeler commented 11 months ago

This is hard to explain.

Consider the following starting state:

PS D:\temp\test> tree /f .\test1; tree /f test3
Folder PATH listing for volume DATA
Volume serial number is 6466-2168
D:\TEMP\TEST\TEST1
│   fizzbuzz.txt
│   foo.txt
│
└───foo
        fizzbuzz2.txt
        foo2.txt

Folder PATH listing for volume DATA
Volume serial number is 6466-2168
D:\TEMP\TEST\TEST3
No subfolders exist

In this example, the -Path ends with a wildcard. The -Exclude parameter is excluding the foo subfolder and foo.txt.

PS D:\temp\test> Copy-Item -Path .\test1\* -Destination .\test3\ -Recurse -Exclude foo* -Verbose; tree /f test3
VERBOSE: Performing the operation "Copy File" on target "Item: D:\temp\test\test1\fizzbuzz.txt Destination: D:\temp\test\test3\fizzbuzz.txt".
Folder PATH listing for volume DATA
Volume serial number is 6466-2168
D:\TEMP\TEST\TEST3
    fizzbuzz.txt

No subfolders exist

In this example, the -Path does not end with a wildcard. The -Exclude parameter is excluding the foo.txt and foo2.txt, but not the foo subfolder.

PS D:\temp\test> del .\test3\* -Recurse -Force
PS D:\temp\test> Copy-Item -Path .\test1 -Destination .\test3\ -Recurse -Exclude foo* -Verbose; tree /f test3
VERBOSE: Performing the operation "Copy Directory" on target "Item: D:\temp\test\test1 Destination: D:\temp\test\test3\test1".
VERBOSE: Performing the operation "Create Directory" on target "Destination: D:\temp\test\test3\test1".
VERBOSE: Performing the operation "Copy File" on target "Item: D:\temp\test\test1\fizzbuzz.txt Destination: D:\temp\test\test3\test1\fizzbuzz.txt".
VERBOSE: Performing the operation "Copy Directory" on target "Item: D:\temp\test\test1\foo Destination: D:\temp\test\test3\test1\foo".
VERBOSE: Performing the operation "Create Directory" on target "Destination: D:\temp\test\test3\test1\foo".
VERBOSE: Performing the operation "Copy File" on target "Item: D:\temp\test\test1\foo\fizzbuzz2.txt Destination: D:\temp\test\test3\test1\foo\fizzbuzz2.txt".
Folder PATH listing for volume DATA
Volume serial number is 6466-2168
D:\TEMP\TEST\TEST3
└───test1
    │   fizzbuzz.txt
    │
    └───foo
            fizzbuzz2.txt
sdwheeler commented 11 months ago

I don't know how we can explain this behavior in the documentation better than we already have. This is a strange edge case. If you want to be sure the right files get copied, you should run the command with -WhatIf first.