0

I have a folder hierarchy with a lot of files. I need to copy all folders and only selected files. For this purposes I write script:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
$files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" }
$Destination = "D:\test\"
Copy-Item $files -Destination $Destination -recurse

When I execute variable $files, it returns correct path:

enter image description here

But when I execute Copy-Item it returns not full path:

enter image description here

Perhaps my approach is wrong. If so, how to copy entire folder structure, and only selected files (in this case system.serviceModel.client.config file)?

UPD1 Ok, I've found, how to copy only folders:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181\"
$Destination = "D:\test\"
Copy-Item $path $Destination -Filter {PSIsContainer} -Recurse -Force

But how to copy only selected files, preserving their location? What needs to be in $Destination variable?

$files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" } | % { Copy-Item -Path $_.FullName -Destination $Destination }
0

4 Answers 4

2

This code would keep the directory structure the same too

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181\"
$Destination = "D:\test\"
$fileName = "system.serviceModel.client.config"
Get-ChildItem -Path $path -Recurse |  ForEach-Object {
    if($_.Name -like $fileName) {
        $dest = "$Destination$(($_.FullName).Replace($path,''))"
        $null = New-Item $dest -Force
        Copy-Item -Path $_.FullName -Destination $dest -Force
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately, first variant doesn't copied any files at all, and second - only one copy of file system.serviceModel.client.config was copied in root of D:\test, without any folder structure
@VasiliyVegas based on your comments I edited my answer. Hopefully, it works now.
0

To copy the whole folder structure AND files with a certain name, below code should do what you want:

$Source      = 'D:\Drop\SOA-ConfigurationManagement - Test\181'
$Destination = 'D:\test'
$FileToCopy  = 'system.serviceModel.client.config'

# loop through the source folder recursively and return both files and folders
Get-ChildItem -Path $Source -Recurse | ForEach-Object {
    if ($_.PSIsContainer) {
        # if it's a folder, create the new path from the FullName property
        $targetFolder = Join-Path -Path $Destination -ChildPath $_.FullName.Substring($Source.Length)
        $copyFile = $false
    }
    else {
        # if it's a file, create the new path from the DirectoryName property
        $targetFolder = Join-Path -Path $Destination -ChildPath $_.DirectoryName.Substring($Source.Length)
        # should we copy this file? ($true or $false)
        $copyFile = ($_.Name -like "*$FileToCopy*")
    }
    # create the target folder if this does not exist
    if (!(Test-Path -Path $targetFolder -PathType Container)) {
        $null = New-Item -Path $targetFolder -ItemType Directory
    }
    if ($copyFile) {
        $_ | Copy-Item -Destination $targetFolder -Force
    }
}

Comments

0

try this

$path = 'D:\Drop\SOA-ConfigurationManagement - Test\181\'
$Destination = 'D:\test\'

$files = Get-ChildItem -Path $path -Recurse -File | where Name -like "*system.serviceModel.client.config*" | %{

$Dir=$_.DirectoryName.Replace($path, $Destination)
$NewPAthFile=$_.FullName.Replace($path, $Destination)

#create dir if not exists
New-Item -Path $Dir -ItemType Directory -Force -ErrorAction SilentlyContinue

#copy file in new dir
Copy-Item $_.FullName $NewPAthFile 


}

Comments

0

With minimal changes I'd suggest the following:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
$files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" }
$Destination = "D:\test\"
$files | % { $_ | Copy-Item -Destination $Destination -recurse }

You can even put the whole copy on one line:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
$Destination = "D:\test\"
Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" } | % { $_ | Copy-Item -Destination $Destination -recurse }

Copy-Item can find the path from the stream of input objects but it doesn't seem to be able to take a collection of System.IO.FileInfo objects as an argument to Path.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.