powershell copy all folders and files in folder - powershell

Probably very easy for you guys.
I want to copy all the folders and files from this path c:\default\
to this destination c:\environment\customfolder\
in the folder customerfolder are other folders with different names.
It should only copy the files and folders to the destination Where the customfolder contains the name DEMO_test
What is the best and easiest way to do that?
should I use for-each?
thanks for your help.
Sorry I should be more clear. ;-)
I have a folder c:\default
All the files and sub-folders in that folder c:\default
should be copied to these folders
c:\environment\customfolder\demo_test
c:\environment\customfolder\demo_test01
c:\environment\customfolder\demo_test02
c:\environment\customfolder\demo_test03
I know it should be possible to copy all files and sub-folders from this path (source)c:\default\
to this path (destination)c:\environment\customfolder\
And only copy it to the folders if they have the name (like) demo_test*
Is that question better?
thanks.

Get a list of files:
Get-ChildItem -Path "C:\default\" -Recurse
The -Recurse parameter searches subfolders.
Now filter the list to show only files that fit a certain pattern
Get-ChildItem -Path "C:\default\" -Recurse |
Where-Object Name -like "*test*"
Note that the pipe | is effectively chaining these commands together.
Now copy the filtered list of items to a destination folder:
Get-ChildItem -Path "C:\default\" -Recurse |
Where-Object Name -like "*test*" |
Copy-Item -Destination "C:\destination\"

if i understood you corectly you have flat structure of catalogs:
SOURCE:
C\Catalog[lookupCatalogs]\files
DEST:
c:\Catalog\SomeCatlogs[lookupCatalogs]\files
if yes,
this function should be ok:
function copy-TestdemoFolders
{
param ($source,
$destination,
$filter,
$recursive = $false)
$folders = Get-ChildItem $source -filter $filter -Directory
$folders | % {
$copyPath = Join-Path $destination $_.name
if (!(Test-Path $copyPath))
{
New-Item $copyPath -ItemType Directory | Out-Null
"Created New Folder: $($_.name)"
}
$scriptBlock = { Get-ChildItem $_.Fullname }
if ($recursive -eq $true)
{
$scriptBlock = { Get-ChildItem $_.Fullname -Recurse }
}
Invoke-Command -ScriptBlock $scriptBlock | %{
Copy-Item $_.Fullname $copyPath -ErrorAction SilentlyContinue
if (!($?)) { $error[0].Exception.Message }
}
}
}
copy-TestdemoFolders -source 'C:\Source' -filter "*demo_test*" -destination D:\TEST
You can recursively copy files from subfolders to [lookupCatalog] with switch copy-TestdemoFolders -source 'C:\Source' -filter "*demo_test*" -destination D:\TEST -recursive:$true

Related

Copy-Item and exclude folders

I need to copy all of my c:\inetpub directory to a new location but exclude the following folders and their subfolders:
c:\inetpub\custerr
c:\inetpub\history
c:\inetpub\logs
c:\inetpub\temp
c:\inetpub\wwwroot
So far I am doing this:
# Directory name is created with a format string
$dirName = "\\servername\folder1 _ {0}\inetpub" -f (get-date).ToString("yyyy-MM-dd-hh-mm-ss")
$dirName # Check the output
# Create dir if needed
if(-not (test-path $dirName)) {
md $dirName | out-null
} else {
write-host "$dirName already exists!"
}
#Copy Backup File to Dir
Copy-Item "\\servername\c$\inetpub\*" $dirName -recurse
This is a simple example of something you could do. Build an array of the parent folders that you want to exclude. Since you are accessing them via UNC paths we cannot really use the c:\ path (We can get around this but what I am about to show should be good enough.).
Then use Get-ChildItem to get all the folders in the inetpub directory. Filter out the exclusions using -notin and pass the rest to Copy-Item
$excludes = "custerr","history","logs","temp","wwwroot"
Get-ChildItem "c:\temp\test" -Directory |
Where-Object{$_.Name -notin $excludes} |
Copy-Item -Destination $dirName -Recurse -Force
You need at least PowerShell 3.0 for this to work.
Copy-Item -Path (Get-Item -Path "$path\*" -Exclude ('Folder1', 'File.cmd', 'File.exe', 'Folder2')).FullName -Destination $destination -Recurse -Force
Replace:
$path by your source folder
('Folder1', 'File.cmd', 'File.exe', 'Folder2') by your specific files/folder to exclude
$destination by your destination folder
Oh, the answer was SO simple, but it seems we are all PowerShell noobs.
New-Item -ItemType Directory -Force -Path $outDir # directory must exist
Copy-Item $inDir\* $outDir -Exclude #("node_modules",".yarn") -Recurse
It's the \* that makes it work.
PowerShell is awesome, but...
I wrote this for daily use and packaged it in the script module, it maintains all the directory structure and supports wildcards:
function Copy-Folder {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[String]$FromPath,
[Parameter(Mandatory)]
[String]$ToPath,
[string[]] $Exclude
)
if (Test-Path $FromPath -PathType Container) {
New-Item $ToPath -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
Get-ChildItem $FromPath -Force | ForEach-Object {
# avoid the nested pipeline variable
$item = $_
$target_path = Join-Path $ToPath $item.Name
if (($Exclude | ForEach-Object { $item.Name -like $_ }) -notcontains $true) {
if (Test-Path $target_path) { Remove-Item $target_path -Recurse -Force }
Copy-Item $item.FullName $target_path
Copy-Folder -FromPath $item.FullName $target_path $Exclude
}
}
}
}
Just call the Copy-Folder -FromPath inetpub -ToPath new-inetpub -Exclude custerr,history,logs,temp,wwwroot
The -FromPath and -ToPath can be omitted,
Copy-Folder inetpub new-inetpub -Exclude custerr,history,logs,temp,wwwroot
You can do something along the lines of:
?{$_.fullname -notmatch '\\old\\'}
after you get a hold of all your folders to filter them down.
This example would exclude anything containing "old" in the name. You can do this for directory you wish to exclude.
A full example:
C:\Example*" -include "*.txt -Recurse |
?{$_.fullname -notmatch '\\old\\'}|
% {Copy-Item $_.fullname "C:\Destination\"}
For multiple excludes you can use -And :
C:\Example*" -include "*.txt -Recurse |
?{$_.fullname -notmatch '\\old\\' -And $_.fullname -notmatch '\\old2\\'}|
% {Copy-Item $_.fullname "C:\Destination\"}

PowerShell - Copy specific files from specific folders

So, the folder structure looks like this:
SourceFolder
file1.txt
file1.doc
Subfolder1
file2.txt
file2.doc
SubSubFolder
file3.txt
doc3.txt
What I want to do is copy all .txt files from folders, whose (folder) names contains the eng, to a destination folder. Just all the files inside the folder - not the file structure.
What I used is this:
$dest = "C:\Users\username\Desktop\Final"
$source = "C:\Users\username\Desktop\Test1"
Copy-Item $source\eng*\*.txt $dest -Recurse
The problem is that it copies the .txt files only from each parent folder but not the sub-folders.
How can I include all the sub-folders in this script and keep the eng name check as well? Can you please help me?
I am talking about PowerShell commands. Should I use robocopy instead?
Yet another PowerShell solution :)
# Setup variables
$Dst = 'C:\Users\username\Desktop\Final'
$Src = 'C:\Users\username\Desktop\Test1'
$FolderName = 'eng*'
$FileType = '*.txt'
# Get list of 'eng*' file objects
Get-ChildItem -Path $Src -Filter $FolderName -Recurse -Force |
# Those 'eng*' file objects should be folders
Where-Object {$_.PSIsContainer} |
# For each 'eng*' folder
ForEach-Object {
# Copy all '*.txt' files in it to the destination folder
Copy-Item -Path (Join-Path -Path $_.FullName -ChildPath '\*') -Filter $FileType -Destination $Dst -Force
}
You can do this :
$dest = "C:\NewFolder"
$source = "C:\TestFolder"
$files = Get-ChildItem $source -File -include "*.txt" -Recurse | Where-Object { $_.DirectoryName -like "*eng*" }
Copy-Item -Path $files -Destination $dest
Another take:
$SourceRoot = <Source folder path>
$TargetFolder = <Target folder path>
#(Get-ChildItem $SourceRoot -Recurse -File -Filter *.txt| Select -ExpandProperty Fullname) -like '*\eng*\*' |
foreach {Copy-Item $_ -Destination $TargetFolder}
It may be easier to first get a list of all the folders that contain eng in the name.
$dest = "C:\Users\username\Desktop\Final"
$source = "C:\Users\username\Desktop\Test1"
$engFolders = Get-ChildItem $source -Directory -Recurse | Where { $_.BaseName -match "^eng" }
Foreach ($folder In $engFolders) {
Copy-Item ($folder.FullName + "\*.txt") $dest
}
Fine to do that with powershell. Try:
$dest = "C:\Users\username\Desktop\Final"
$source = "C:\Users\username\Desktop\Test1"
Get-ChildItem $source -filter "*.txt" -Recurse | Where-Object { $_.DirectoryName -match "eng"} | ForEach-Object { Copy-Item $_.fullname $dest }

Powershell script to search for file types from a list of machines, then copy results into directories named after the machine

Here's what I have working so far. It's searching a list of computers placing all the files from all the machines in one folder.
I'm trying to get the files located to be placed in a folder named after the machine that they came from. Any ideas anyone?
Get-Content C:\computers.txt | Foreach-Object {
$ComputerName = $_
Get-Childitem "\\$ComputerName\c$\Documents and Settings\**\desktop","\\$ComputerName\c$\Documents and Settings\**\My Documents" -Include *.xls*, *.doc*, *.txt, *.pdf, *.jpg -Recurse -Force
} | Copy-Item -Destination \\destination\share
Move the Copy-Item inside the loop and add a statement to create the destination folder:
$extensions = '*.xls*', '*.doc*', '*.txt', '*.pdf', '*.jpg', '*.pub'
Get-Content C:\computers.txt | % {
$ComputerName = $_
$dst = "\\destination\share\$ComputerName"
$src = "\\$ComputerName\c$\Documents and Settings\**\desktop",
"\\$ComputerName\c$\Documents and Settings\**\My Documents"
New-Item -ItemType Directory $dst
Get-Childitem $src -Include $extensions -Recurse -Force |
Copy-Item -Destination $dst\
}

Copy-item Files in Folders and subfolders in the same directory structure of source server using PowerShell

I am struggling really hard to get this below script worked to copy the files in folders and sub folders in the proper structure (As the source server).
Lets say, there are folders mentioned below:
Main Folder: File aaa, File bbb
Sub Folder a: File 1, File 2, File 3
Sub Folder b: File 4, File 5, File 6
Script used:
Get-ChildItem -Path \\Server1\Test -recurse | ForEach-Object {
Copy-Item -LiteralPath $_.FullName -Destination \\server2\test |
Get-Acl -Path $_.FullName | Set-Acl -Path "\\server2\test\$(Split-Path -Path $_.FullName -Leaf)"
}
Output:
File aaa, File bbb
Sub Folder a (Empty Folder)
Sub Folder b (Empty Folder)
File 1, File 2, File 3, File 4, File 5, File 6.
I want the files to get copied to their respective folders (Like the source folders). Any further help is highly appreciated.
This can be done just using Copy-Item. No need to use Get-Childitem. I think you are just overthinking it.
Copy-Item -Path C:\MyFolder -Destination \\Server\MyFolder -recurse -Force
I just tested it and it worked for me.
edit: included suggestion from the comments
# Add wildcard to source folder to ensure consistent behavior
Copy-Item -Path $sourceFolder\* -Destination $targetFolder -Recurse
If you want to mirror same content from source to destination, try following one.
function CopyFilesToFolder ($fromFolder, $toFolder) {
$childItems = Get-ChildItem $fromFolder
$childItems | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $toFolder -Recurse -Force
}
}
Test:
CopyFilesToFolder "C:\temp\q" "c:\temp\w"
one time i found this script, this copy folder and files and keep the same structure of the source in the destination, you can make some tries with this.
# Find the source files
$sourceDir="X:\sourceFolder"
# Set the target file
$targetDir="Y:\Destfolder\"
Get-ChildItem $sourceDir -Include *.* -Recurse | foreach {
# Remove the original root folder
$split = $_.Fullname -split '\\'
$DestFile = $split[1..($split.Length - 1)] -join '\'
# Build the new destination file path
$DestFile = $targetDir+$DestFile
# Move-Item won't create the folder structure so we have to
# create a blank file and then overwrite it
$null = New-Item -Path $DestFile -Type File -Force
Move-Item -Path $_.FullName -Destination $DestFile -Force
}
I had trouble with the most popular answer (overthinking). It put AFolder in the \Server\MyFolder\AFolder and I wanted the contents of AFolder and below in MyFolder. This didn't work.
Copy-Item -Verbose -Path C:\MyFolder\AFolder -Destination \\Server\MyFolder -recurse -Force
Plus I needed to Filter and only copy *.config files.
This didn't work, with "\*" because it did not recurse
Copy-Item -Verbose -Path C:\MyFolder\AFolder\* -Filter *.config -Destination \\Server\MyFolder -recurse -Force
I ended up lopping off the beginning of the path string, to get the childPath relative to where I was recursing from. This works for the use-case in question and went down many subdirectories, which some other solutions do not.
Get-Childitem -Path "$($sourcePath)/**/*.config" -Recurse |
ForEach-Object {
$childPath = "$_".substring($sourcePath.length+1)
$dest = "$($destPath)\$($childPath)" #this puts a \ between dest and child path
Copy-Item -Verbose -Path $_ -Destination $dest -Force
}
Here you go.
Function Backup-Files {
[CmdletBinding()]
Param (
[Parameter(Mandatory)]
[System.IO.FileInfo[]]$Source,
[Parameter(Mandatory)]
[String]$Destination
)
if (!(Test-Path $Destination)) {[void][System.IO.Directory]::CreateDirectory($Destination)}
ForEach ($File in $Source) {
$SourceRoot = $(Convert-Path $File.PSParentPath).split('\')[0]
$NewFile = $($File.FullName).Replace($SourceRoot,$Destination)
$NewDir = $($File.DirectoryName).Replace($SourceRoot,$Destination)
[void][System.IO.Directory]::CreateDirectory($NewDir)
Copy-Item -Path $File.FullName -Destination $NewFile -Force
}
}
Examples
<#
.SYNOPSIS
Copy FileInfo object or array to a new destination while retaining the original directory structure.
.PARAMETER Source
FileInfo object or array. (Get-Item/Get-ChildItem)
.PARAMETER Destination
Path to backup source data to.
.NOTES
Version (Date): 1.0 (2023-02-04)
Author: Joshua Biddle (thebiddler#gmail.com)
Purpose/Change: Initial script development.
Known Bugs:
.EXAMPLE
Backup-Files -Source $(Get-ChildItem -Path 'C:\Users\*\Documents' -Recurse -Force -Exclude 'My Music','My Pictures','My Videos','desktop.ini' -ErrorAction SilentlyContinue) -Destination "C:\Temp\UserBackup"
.EXAMPLE
Backup-Files -Source $(Get-ChildItem -Path 'C:\Users\*\Desktop' -Exclude "*.lnk","desktop.ini" -Recurse -Force -ErrorAction SilentlyContinue) -Destination "C:\Temp\UserBackup"
#>
I wanted a solution to copy files modified after a certain date and time which mean't I need to use Get-ChildItem piped through a filter. Below is what I came up with:
$SourceFolder = "C:\Users\RCoode\Documents\Visual Studio 2010\Projects\MyProject"
$ArchiveFolder = "J:\Temp\Robin\Deploy\MyProject"
$ChangesStarted = New-Object System.DateTime(2013,10,16,11,0,0)
$IncludeFiles = ("*.vb","*.cs","*.aspx","*.js","*.css")
Get-ChildItem $SourceFolder -Recurse -Include $IncludeFiles | Where-Object {$_.LastWriteTime -gt $ChangesStarted} | ForEach-Object {
$PathArray = $_.FullName.Replace($SourceFolder,"").ToString().Split('\')
$Folder = $ArchiveFolder
for ($i=1; $i -lt $PathArray.length-1; $i++) {
$Folder += "\" + $PathArray[$i]
if (!(Test-Path $Folder)) {
New-Item -ItemType directory -Path $Folder
}
}
$NewPath = Join-Path $ArchiveFolder $_.FullName.Replace($SourceFolder,"")
Copy-Item $_.FullName -Destination $NewPath
}

make copy of folder tree without files

I need to make copy of folder with subfolders, but do it without any files, except data that include folder "Project".
So I need to do new folders tree, but it should include only files that was present in subfolder named "Project".
ok, My solution:
$folder = dir D:\ -r
$folder
foreach ($f in $folder)
{
switch ($f.name)
{
"project"
{
Copy-Item -i *.* $f.FullName D:\test2
}
default
{
Copy-Item -exclude *.* $f.FullName D:\test2
}
}
}
Use xcopy /t to copy only the folder structure and then copy the Project folders separately. Something like this:
'test2\' | Out-File D:\exclude -Encoding ASCII
xcopy /t /exclude:d:\exclude D:\ D:\test2
gci -r -filter Project | ?{$_.PSIsContainer} | %{ copy -r $_.FullName d:\test2}
ri d:\exclude
Another solution:
$source = "c:\dev"
$destination = "c:\temp\copydev"
Get-ChildItem -Path $source -Recurse -Force |
Where-Object { $_.psIsContainer } |
ForEach-Object { $_.FullName -replace [regex]::Escape($source), $destination } |
ForEach-Object { $null = New-Item -ItemType Container -Path $_ -Force }
Get-ChildItem -Path $source -Recurse -Force |
Where-Object { -not $_.psIsContainer -and (Split-Path $_.PSParentPath -Leaf) -eq "Project"} |
Copy-Item -Force -Destination { $_.FullName -replace [regex]::Escape($source), $destination }
Use Get-ChildItem to recurse over folders and remap structure using New-Item. Within recursion, you can easily check for "Project".
First, create the directory structure:
xcopy D:\source D:\destination /t /e
Now, iterate through the source directory, copying every file in a Project directory:
Get-ChildItem D:\Source * -Recurse |
# filter out directories
Where-Object { -not $_.PsIsContainer } |
# grab files that are in Project directories
Where-Object { (Split-Path -Leaf (Split-Path -Parent $_.FullName)) -eq 'Project' } |
# copy the files from source to destination
Copy-Item -Destination ($_.FullName.Replace('D:\source', 'D:\destination'))