keepcalculator

06 Numbers and Powers

PowerShell Copy Folder and Subfolders: Full Guide

Card No. 06·40475 · Updated · Standard formula, shown below

To copy a folder and all its subfolders and files in PowerShell, use the Copy-Item cmdlet with the -Recurse parameter. For example, Copy-Item -Path "C:\Source" -Destination "D:\Backup" -Recurse copies the entire Source folder tree to D:\Backup. This guide explains the syntax, common pitfalls, and advanced techniques like filtering and preserving timestamps.

Why Copy-Item -Recurse Is the Standard

PowerShell’s Copy-Item is the direct equivalent of the Windows copy command but with more control. Without -Recurse, Copy-Item copies only the folder itself (an empty folder) or fails if the destination already exists. The -Recurse switch tells PowerShell to traverse every subdirectory and copy all files and folders, mirroring the source structure.

Here’s a minimal working example:

Copy-Item -Path "C:\Projects\Website" -Destination "D:\Backups\Website" -Recurse

This creates D:\Backups\Website if it doesn’t exist and copies everything inside C:\Projects\Website into it. If the destination folder already exists, PowerShell copies the source folder into it, resulting in D:\Backups\Website\Website. This behavior surprises many users; see the “Common Mistakes� section below.

How Copy-Item Handles Folders and Files

Think of Copy-Item as a file-system copier that respects the source’s hierarchy. When you specify -Recurse, it performs a depth-first traversal: it creates the destination folder, then copies each file and subfolder recursively. Key points:

  • Empty folders are copied – unlike robocopy’s default behavior, PowerShell copies empty directories when using -Recurse.
  • Hidden and system files are copied by default, unless you filter them with -Exclude or -Include.
  • File attributes (like ReadOnly) are preserved, but timestamps are not preserved by default. The copied files get the current time as the creation/modified time.
  • Symbolic links are copied as links, not as the target content, unless you use -Force (which may follow links in some PowerShell versions).

If you need to preserve exact timestamps, use robocopy (built into Windows) or the .NET System.IO.Directory class, as shown later.

Choosing the Right Copy Method

PowerShell offers several ways to copy folders, each with trade-offs:

  • Copy-Item -Recurse – Best for simple, one-off copies in scripts. It’s easy to read and works on PowerShell 5.1 and 7+.
  • robocopy – A command-line tool that excels at large or complex copies. It supports multi-threading, restartable copies, and timestamp preservation. Use robocopy "C:\Source" "D:\Dest" /E to copy all subfolders including empty ones.
  • Start-BitsTransfer – Good for copying over a network; it uses Background Intelligent Transfer Service (BITS) and can resume interrupted transfers.
  • .NET System.IO.Directory.Copy – A low-level method that gives full control but requires manual recursion.

For most users, Copy-Item -Recurse is sufficient. If you need to copy millions of files or want a progress bar, consider robocopy.

Step-by-Step: Copying a Folder with Subfolders

  1. Open PowerShell (as Administrator if copying system folders).
  2. Define the source and destination as variables for clarity:
    $source = "C:\Data\Documents"
    $dest = "D:\Archive\Documents"
  3. Run the copy command:
    Copy-Item -Path $source -Destination $dest -Recurse -Force

    The -Force parameter overwrites existing files and allows copying hidden/system items.

  4. Verify the result:
    Get-ChildItem -Path $dest -Recurse | Measure-Object | Select-Object Count

    This counts the files and folders copied.

If you want to see what would happen without actually copying, add the -WhatIf switch:

Copy-Item -Path $source -Destination $dest -Recurse -WhatIf

This lists the actions PowerShell would take, which is invaluable for testing scripts.

Common Mistakes and How to Avoid Them

  • Destination already exists – As mentioned, if D:\Archive\Documents exists, PowerShell creates D:\Archive\Documents\Documents. To avoid this, either use a destination that doesn’t exist yet, or copy the contents with a wildcard: Copy-Item -Path "$source\*" -Destination $dest -Recurse.
  • Forgetting -Recurse – Without it, you get an error like “The directory is not empty� or a partial copy. Always double-check the command.
  • Path quoting issues – If paths contain spaces, enclose them in quotes. Use "C:\My Folder" not C:\My Folder.
  • Using -Include without -Recurse – The -Include parameter only works with -Recurse or when the path ends in \*. For example, to copy only .txt files: Copy-Item -Path "$source\*" -Destination $dest -Recurse -Include *.txt.
  • Permission errors – If you get “Access denied�, run PowerShell as Administrator or ensure the destination folder allows write access.

Advanced Techniques: Filtering and Preserving Timestamps

Filtering files – To copy only certain file types, use -Filter (faster than -Include) or -Exclude. For example, to copy all files except temporary ones:

Copy-Item -Path $source -Destination $dest -Recurse -Exclude "*.tmp"

Preserving timestamps – PowerShell’s Copy-Item does not preserve the original modification time. To keep timestamps, use robocopy:

robocopy "C:\Source" "D:\Dest" /E /COPY:DAT

The /COPY:DAT flag copies Data, Attributes, and Timestamps. You can also use robocopy to mirror a folder exactly with /MIR (use with caution – it deletes files in the destination that don’t exist in the source).

Copying over a network – If the destination is a UNC path like \\Server\Share\Folder, ensure you have the right credentials. Use New-PSDrive to map a network drive, or pass credentials to Copy-Item via -Credential (only in PowerShell 7+).

Frequently Asked Questions

Q: How do I copy a folder and subfolders without overwriting existing files?
A: Use Copy-Item -Recurse without -Force. By default, PowerShell will prompt before overwriting if the destination file exists. To skip overwriting entirely, you can use robocopy with the /XC (exclude changed) and /XN (exclude newer) flags, or use a script that checks for existence first.

Q: Why does my copied folder end up inside the destination folder?
A: This happens when the destination folder already exists. PowerShell copies the source folder into the destination, creating a nested folder. To copy the contents of the source into the destination, add a wildcard to the source path: Copy-Item -Path "C:\Source\*" -Destination "D:\Dest" -Recurse.

Q: Can I copy a folder and subfolders to a remote computer?
A: Yes, if the remote computer has a shared folder and you have access. Use a UNC path as the destination: Copy-Item -Path "C:\Local" -Destination "\\RemotePC\Share\Folder" -Recurse. For large transfers, consider using Start-BitsTransfer which is more reliable over unstable networks.

Q: How do I copy only new or modified files?
A: PowerShell’s Copy-Item doesn’t have a built-in “only newer� option. Use robocopy with the /XO (exclude older) and /XN (exclude newer) flags to copy only files that are newer than the destination, or use /XX to include only extra files. Alternatively, write a script that compares timestamps using Get-Item.

Q: Does Copy-Item preserve file permissions (ACLs)?
A: No, by default Copy-Item does not copy NTFS permissions. To copy ACLs, use robocopy with the /COPY:DAT flag (which includes security) or use Get-Acl and Set-Acl in a script. Note that copying ACLs may require administrator privileges.

Q: What is the difference between Copy-Item and Move-Item?
A: Copy-Item duplicates the folder and its contents, leaving the original intact. Move-Item transfers the folder to the new location, deleting the original. Both support -Recurse for subfolders, but Move-Item can be faster on the same drive because it just changes the file system pointers.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →