Fr. Vandecan
asked on
PowerShell. Copy 2 files to all subfolders of a tree : why is the command doing nothing?
Dear,
I have to copy 2 files containted in one folder to dynamic set of sub folder.
Let's say
files are stored in c:\template
Destination folders are c:\Documents\A .......; c:\Documents\Z
I want the 2 files into all subfolders of c:\Documents
I have this but seems not working...
Get-ChildItem -Path c:\template | ?{ $_.PSIsContainer } | Copy-Item c:\documents $_.fullname
I have to copy 2 files containted in one folder to dynamic set of sub folder.
Let's say
files are stored in c:\template
Destination folders are c:\Documents\A .......; c:\Documents\Z
I want the 2 files into all subfolders of c:\Documents
I have this but seems not working...
Get-ChildItem -Path c:\template | ?{ $_.PSIsContainer } | Copy-Item c:\documents $_.fullname
Maybe because is missing the -Recurse switch, and because fullname give you the full Path and Name and you're not even trying to write into "C:\documents".
Wrong code:
Corrected code: (will post it shortly it has issues the one I've commented previously)
Function CopyInfo, CopyInfo -sourceDir $Source -targetDir $FolderName (just define $sourcedir and $targetDir variables.
Wrong code:
Get-ChildItem -Path c:\template -recursive | ?{ $_.PSIsContainer } | Copy-Item c:\documents $_.fullname
Corrected code: (will post it shortly it has issues the one I've commented previously)
Function CopyInfo, CopyInfo -sourceDir $Source -targetDir $FolderName (just define $sourcedir and $targetDir variables.
function CopyInfo{
[CmdletBinding()]
param(
[Parameter(Position=0,mandatory=$true)] [string]$sourceDir,
[Parameter(Position=1,mandatory=$true)] [string]$targetDir
)
if(! [System.IO.Directory]::Exists($targetDir) ){
#create new directory
[System.IO.Directory]::CreateDirectory($targetDir) | Out-Null
}
#get source files
foreach($file in [System.IO.Directory]::GetFiles($sourceDir) ){
$FilePath=[System.IO.Path]::Combine($targetDir, [System.IO.Path]::GetFileName($file))
if(![System.IO.File]::Exists($FilePath) ){
#Write-Output "Writing $file"
[System.IO.File]::Copy($file, $FilePath)
}
else{
$FileInfoExisting = new-object System.IO.FileInfo($FilePath)
$FileInfoNew = new-object System.IO.FileInfo($file)
#3 items check
#1 check creationtime (preserve the newest)
#2 lastwriteTime (preserve newest)
#3 Length
#Write-Output "Overwriting $file"
[System.IO.File]::Delete($FilePath)
[System.IO.File]::Copy($file, $FilePath)
}
}
foreach($dir in [System.IO.Directory]::GetDirectories($sourceDir) ){
$test = [System.IO.Path]::Combine($targetDir, (New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $dir).Name)
CopyInfo -sourceDir $dir -targetDir $test
}
}
If you only wanted to copy into a single folder
Since you want to copy into multipe folders, you'll need to do it different. If you do not want to be selective, just copy into all first-level subfolders of C:\Documents, which I assume:
Get-ChildItem -c:\template\* -File | Copy-Item -destination c:\documents
would be correct.Since you want to copy into multipe folders, you'll need to do it different. If you do not want to be selective, just copy into all first-level subfolders of C:\Documents, which I assume:
foreach ($folder in Get-ChildItem c:\Template -Directory)
{
Get-ChildItem C:\Template\* -File | Copy-Item -Destination $folder
}
Instead of that, you can enumerate manually in the foreach.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Amazing !!!
Glad to help. :)
I see my second suggestion has a typo, and should be
foreach ($folder in Get-ChildItem c:\Documents -Directory)
{
Get-ChildItem C:\Template\* -File | Copy-Item -Destination $folder
}
This and Jeremy's code are valid, and which one to use is a matter of preference only.
Open in new window