Kae Travis

Use PowerShell Copy-Item to Copy a File or Folder Including Mirror Copy

Tags:

This post explains how to use PowerShell Copy-Item to copy a file or folder including mirror copy!

Throughout this example, consider that we have created the following folder/file structure:

C:\alkanesource
│   file1.txt
│   file2.log
│   file3.zip
└───alkanesubfolder
│   file4.ps1
C:\alkanedestination

C:\alkanesource contains all of the files and folders we want to copy – this is our source location. And C:\alkanedestination is an empty folder where we want to copy files and folder to – this is our destination location.

Copy a Single Known File Name using Copy-Item

We can copy a single known file name to a destination is as simple as:

Copy-Item -Path "C:\alkanesource\file1.txt" -Destination "C:\alkanedestination"

Result

C:\alkanedestination
│   file1.txt

Copy Multiple Known File Names using Copy-Item

We can copy multiple known filenames by providing a string array containing file paths to the -Path parameter like so:

$multipleKnownFilenames = "C:\alkanesource\file1.txt","C:\alkanesource\file2.log"
Copy-Item -Path $multipleKnownFilenames -Destination "C:\alkanedestination"

Result

C:\alkanedestination
│   file1.txt
│   file2.log

Filter Copied Files using Include and Exclude (Excluding Files in Sub folders)

We can include or exclude certain file names or types from a copy operation using the -Include and -Exclude parameters.

Here is an example of including the file types of *.log and *.zip – note that the source copy path indicates we’re copying files and is denoted by *.*.

$filesToInclude = "*.log","*.zip"
Copy-Item -Path "C:\alkanesource\*.*" -Destination "C:\alkanedestination" -Include $filesToInclude

Result

C:\alkanedestination
│   file2.log
│   file3.zip

Here is an example of excluding the file names file3.zip and file1.txt – note again that the source path indicates we’re copying files and is denoted by *.*.

$filesToExclude = "file3.zip","file1.txt"
Copy-Item -Path "C:\alkanesource\*.*" -Destination "C:\alkanedestination" -Exclude $filesToExclude

Result

C:\alkanedestination
│   file2.log

Copying All File Names using Copy-Item (Excluding Files in Sub folders)

Here we can copy all files (excluding those in subfolders) from our source folder to the destination folder by using the wildcard “*.*” – the first asterisk represents “any file name” and the second asterisk represents “any file extension”.

Copy-Item -Path "C:\alkanesource\*.*" -Destination "C:\alkanedestination"

Result

C:\alkanedestination
│   file1.txt
│   file2.log
│   file3.zip

You will notice that the previous examples didn’t copy the files contained within alkanesubfolder . Many people think that adding the -recurse parameter will resolve this. But the -recurse parameter only creates a destination folder structure if the source is a folder, not if it is a file. When the source is a file (as in our example above), Copy-Item expects the destination to be a file or a folder that already exists. Which it doesn’t!

Copying All File Names and Sub Folders using Copy-Item

To copy all files and sub folders recursively, instead of targeting files as our source we must instead target the folder. Note that specifying one asterisk represents any wildcard folder:

Copy-Item -Path "C:\alkanesource\*" -Destination "C:\alkanedestination" -Recurse

Result

C:\alkanedestination
│   file1.txt
│   file2.log
│   file3.zip
└───alkanesubfolder 
│   file4.ps1

Note that if we didn’t specify the wildcard (representing any folder), it will also include copying the source folder itself to the destination:

C:\alkanedestination
└───alkanesource
│   file1.txt
│   file2.log
│   file3.zip
└───alkanesubfolder 
│   file4.ps1

Mirror Copying Specific File Names and File Types using Copy-Item

You would think intuitively that we could use the -Include and -Exclude parameters to filter which file names and file types we want to recursively copy like so:

$filesToInclude = "*.log","*.zip"
Copy-Item -Path "C:\alkanesource\*" -Destination "C:\alkanedestination" -Recurse -Include $filesToInclude

But you’d be wrong. Because the -Include and -Exclude parameters don’t support recursion. So we have to go about it a different way by iterating through files manually:

$filesToInclude = "*.log","*.ps1"
$sourceFolder = "C:\alkanesource\"
$destinationFolder = "C:\alkanedestination\"
#loop through each file in source folder
Get-ChildItem -Path $sourceFolder -File -Recurse -Include $filesToInclude | 
Foreach {
#replace source folder with target folder
New-Object PSObject -Prop @{ 
Source = $_.Fullname
Destination = $_.Fullname.Replace($sourceFolder,$destinationFolder)
}
} |
Foreach {
#create target folder if it doesnt exist since copy-item requires it
New-Item -ItemType File -Path $_.Destination -Force | Out-Null
#overwrite with actual file
Copy-Item -Path $_.Source -Destination $_.Destination -Force
}

Result

C:\alkanedestination
│   file1.txt
│   file2.log
│   file3.zip
└───alkanesubfolder 
│   file4.ps1

 

 

 

Use PowerShell Copy-Item to Copy a File or Folder Including Mirror Copy
Use PowerShell Copy-Item to Copy a File or Folder Including Mirror Copy

Leave a Reply