jdids
jdids

Reputation: 571

Powershell - Copy all items from a known subfolder and exclude everything else

I'm trying to copy over some PDFs that are nested inside of a directory.

Here is the structure. There are about 100 directories similar to the structure below

Top Folder

What I'm trying to do is copy everything out of Subfolder1 in each ParentFolder. Subfolder1 has the same name in every ParentFolder.

I can get all of the files using this command

Get-ChildItem -Path 'C:\Temp\Powershell' -Recurse -Include *.pdf

But when I tell it to copy the files over with this command

Get-ChildItem -Path 'C:\Temp\Powershell' -Recurse -Include *.pdf
ForEach-Object {Copy-Item $_.FullName -Destination 'C:\Temp\Destination'}

It gives me this error

Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:2 char:27
+ ForEach-Object {Copy-Item $_.FullName -Destination 'C:\Temp\Destinati ...
+                           ~~~~~~~~~~~
+ CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand

I feel like I'm close, but I want to exclude any directories that aren't named Subfolder1 and copy all of Subfolder1 content recursively. I've tried adding in the folder name in the -Include statement but was unsuccessful.

EDIT With the help of Tomalak, I was able to figure out my issue plus filter it to only look at Subfolder1 through each ParentFolder

Get-ChildItem -Path 'C:\Temp\Powershell' -Recurse -Include *.pdf 
| Where-Object {$_.PSParentPath -like "*Subfolder1*"} 
| ForEach-Object {Copy-Item $_.FullName -Destination 'C:\Temp\Destination'}

Upvotes: 1

Views: 219

Answers (1)

Tomalak
Tomalak

Reputation: 338158

Copy-Item takes input from the pipeline, you don't need to use ForEach-Object at all.

Get-ChildItem -Path 'C:\Temp\Powershell' -Recurse -Include *.pdf | Copy-Item -Destination 'C:\Temp\Destination'

But if you want to, you still need to attach it to the pipeline (note the |):

Get-ChildItem -Path 'C:\Temp\Powershell' -Recurse -Include *.pdf | ForEach-Object {
    Copy-Item $_.FullName -Destination 'C:\Temp\Destination'
}

Your code has it on an extra line with no connection to the previous cmdlet at all.

Upvotes: 2

Related Questions