简体   繁体   中英

PowerShell to copy files to destination's subfolders while excluding certain folders in the destination

So I have danced with this off and on throughout the day and the timeless phrase "There's more than one way to skin a cat" keeps coming to mind so I decided to take to the community.

Scenario:

Source folder "C:\\Updates" has 100 files of various extensions. All need to be copied to the sub-folders only of "C:\\Prod\\" overwriting any duplicates that it may find.

The Caveats:

  1. The sub-folder names (destinations) in "C:\\Prod" are quite dynamic and change frequently.

  2. A naming convention is used to determine which sub-folders in the destination need to be excluded when the source files are being copied (to retain the original versions). For ease of explanation lets say any folder names starting with "!stop" should be excluded from the copy process. (!stop* if wildcards considered)

So, here I am wanting the input of those greater than I to tackle this in PS if I'm lucky. I've tinkered with Copy-Item and xcopy today so I'm excited to hear other's input.

Thanks!

-Chris

Give this a shot:

Get-ChildItem -Path C:\Prod -Exclude !stop* -Directory `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }

This grabs each folder (the -Directory switch ensures we only grab folders) in C:\\Prod that does not match the filter and pipes it to the ForEach-Object command where we are running the Copy-Item command to copy the files to the directory.

The -Directory switch is not available in every version of PowerShell; I do not know which version it was introduced in off the top of my head. If you have an older version of PowerShell that does not support -Directory then you can use this script:

Get-ChildItem -Path C:\Prod -Exclude !stop* `
| Where-Object { $_.PSIsContainer } `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }

To select only sub folders which do not begin with "!stop" do this

$Source = "C:\Updates\*"
$Dest =   "C:\Prod"
$Stop =   "^!stop"

$Destinations = GCI -Path $Dest |?{$_.PSIsContainer -and $_.Name -notmatch $Stop }
ForEach ($Destination in $Destinations) {
  Copy-Item -Path $Source -Destination $Destination.FullName -Force 
}

Edited Now copies all files from Update to subs of Source not beginning with "!stop" The -whatif switch shows what would happen, to arm the script remove the -whatif.

Edit2 Streamlined the script. If also Sub/sub-folders of C:\\Prod shall receive copies include a -rec option to the gci just in front of he pipe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM