Copy-Item: Copying Files like a Boss in PowerShell

Copy-ItemCopying files. It’s not sexy but has to be done. In the GUI, we copy and paste with the clipboard but in PowerShell we have a cmdlet called Copy-Item.

Commands for copying files have been around forever in all shell languages. In PowerShell land, the most popular way to get a copy of a file or folder in your PowerShell script from point A to point B is by using the PowerShell Copy-Item cmdlet. This cmdlet allows us to copy a file and folder while giving us the ability to recurse files in a folder, use wildcards to select the files we need to copy and even use PowerShell Remoting for a file copy!

The Copy-Item cmdlet is a part of the PowerShell provider cmdlets. It’s a generic cmdlet that recognized by it’s Item noun. Most of these provider cmdlets can be used across different providers but in my nearly 10 years of using PowerShell, I’ve only seen Copy-Item to be used with the file system provider.

By using Copy-Item, PowerShell allows a scripter to copy files and folders a number of different ways.

Basic Usage

At it’s most basic, the Copy-Item cmdlet copies a single file from point A to point B using the Path parameter as the source file path and the Destination parameter as the destination folder path.

This cmdlet can also copy empty folders as well. I’ll list item in the C:\EmptyFolder folder and then copy those out.

Perhaps there is a read-only file in the folder. By default, Copy-Item will not overwrite it. To force the override, just add the Force parameter.

Getting Selective with Copy-Item

In addition to copying a single file or folder, we can also copy the entire contents of a folder. The Path parameter of Copy-Item accepts wildcard characters like the asterisk to match one or more characters or the question mark to only match a single character.

Merging Mulitple Folders Together

Another cool feature of Copy-Item is it’s ability to copy multiple folders together at the same time. By passing multiple paths to the Path parameter, Copy-Item will look at each one, copy either the folder or file(s) depending on the path and “merge” them all into the single destination.

Copying Files Recursively

Chances are you’re not going to get lucky and have all files in a single folder with no folders in there as well. We usually run into situations where we’ve got lots of subfolders in the parent folder which files in them too we’d like to copy over. By using the Recurse parameter on Copy-Item, it will gladly look in each subfolder and copy all files and folders in each recursively.

Notice here that I’m piping files and folders from Get-ChildItem directly to Copy-Item. Copy-Item has pipeline support!

Advantages of using the PassThru Parameter

Many cmdlets in PowerShell have a PassThru parameter. Cmdlets that typically return nothing can return the objects they are manipulating using the PassThru parameter. This cmdlet is no different. When I first started scripting, I never used this parameter because I didn’t feel I needed to.

For example, if I wanted to copy a file to a remote location and then reference that file later on in my script I’d do something like this:

This method works but it can be better. Instead of defining a variable for the remote path, why not just capture the object that gets returned from Copy-Item cmdlet when using the PassThru parameter instead? The objects returned will always have the destination file path.

Copying Files Using a PowerShell Remoting Session

One cool feature that came with PowerShell v5 is this cmdlet’s ability to not use the default SMB protocol for transferring a file but instead use WinRM and a PowerShell remote session. By using the Session parameter, Copy-Item uses an existing PowerShell session and transfers the files that way. This is a great way to get around firewalls and when the session communication is encrypted, an extra layer of security as well.

We could have copied the File.txt file over SMB and hoped the C$ admin share was available and used the destination path of \\WEBSRV1\c$. Since we used the ToSession parameter instead, the destination path will always be the path local to the computer the remote session is running under.

Summary

The Copy-Item cmdlet is one of those core PowerShell cmdlets that you’ll use over and over again. In PowerShell, copy files, folders in a number of different ways with it’s simple yet powerful especially with it’s ability to use wildcards, to merge multiple folders of files together and to use existing PowerShell Remoting sessions!

One comment

  • Hi there

    the recurse-parameter is absolutely dissapointing!

    Try this

    & tree D:\111 /f
    Get-ChildItem -Path D:\111 -Recurse | Copy-Item -Destination D:\aaa
    & tree D:\aaa /f

    You´ll see the difference immediatly!

Leave a Reply