PowerShell Copy and Move Files: Copy-Item and Move-Item

PowerShell Copy and Move Files: Copy-Item and Move-Item

PowerShell Tips Editor 4 min read
PowerShell Copy and Move Files: Copy-Item and Move-Item

Automated backup scripts, deployment pipelines, and file organization routines all share one thing: they need to copy files in PowerShell or move them reliably. PowerShell’s Copy-Item and Move-Item cmdlets handle this cleanly — supporting single files, entire directory trees, wildcards, and proper error handling. This guide covers every practical pattern you’ll need for copying and moving files in real scripts.

Copy-Item Basic Syntax

Copy a single file from one location to another:

# Copy a single file
Copy-Item -Path 'C:\Logs\app.log' -Destination 'C:\Backup\app.log'

# Copy without specifying filename (keeps original name)
Copy-Item -Path 'C:\Logs\app.log' -Destination 'C:\Backup\'

# Copy and verify with PassThru (returns the new item object)
$copy = Copy-Item -Path 'C:\Logs\app.log' -Destination 'C:\Backup\' -PassThru
Write-Output "Copied to: $($copy.FullName)"
Copied to: C:\Backup\app.log

The destination folder must already exist. If you copy to a path that ends without a filename, PowerShell uses the original filename. If the destination includes a filename, the file is saved with that name.

Copying an Entire Folder Recursively

Use -Recurse to copy a folder with all its contents:

# Copy folder and all contents
Copy-Item -Path 'C:\Projects\WebApp' -Destination 'C:\Backup\WebApp' -Recurse

# Copy to a new name
Copy-Item -Path 'C:\Projects\WebApp' -Destination 'C:\Projects\WebApp-Backup' -Recurse

# Preview with -WhatIf
Copy-Item -Path 'C:\Projects\WebApp' -Destination 'C:\Backup\WebApp' -Recurse -WhatIf
What if: Performing the operation "Copy Directory" on target
"Item: C:\Projects\WebApp Destination: C:\Backup\WebApp".

Always test with -WhatIf first when copying large directory structures. The destination directory does not need to exist when -Recurse is used — PowerShell creates it automatically.

Moving Files with Move-Item

Move-Item works like Copy-Item but removes the source after the operation:

# Move a file
Move-Item -Path 'C:\Downloads\report.xlsx' -Destination 'C:\Users\Public\Documents\'

# Move and rename simultaneously
Move-Item -Path 'C:\Logs\temp.log' -Destination 'C:\Logs\Archive\2026-05-04.log'

# Move all .log files to an archive folder
Get-ChildItem 'C:\Logs' -Filter '*.log' |
    Move-Item -Destination 'C:\Logs\Archive\'
# Files moved silently. Check Archive folder.

For moves within the same drive, the operation is near-instant (filesystem rename). Cross-drive moves physically copy then delete, so they’re slower for large files.

Overwriting Existing Files with -Force

By default, Copy-Item and Move-Item throw an error if the destination already exists. Use -Force to overwrite:

# Overwrite if destination exists
Copy-Item -Path 'C:\Config\settings.json' -Destination 'C:\Backup\settings.json' -Force

# Move and overwrite
Move-Item -Path 'C:\Staging\deploy.zip' -Destination 'C:\Production\deploy.zip' -Force

# Check if destination exists before forcing
$dest = 'C:\Backup\app.log'
if (Test-Path $dest) {
    Write-Warning "Overwriting: $dest"
}
Copy-Item -Path 'C:\Logs\app.log' -Destination $dest -Force

Copying Multiple Files with Wildcards

Use wildcards in the -Path to copy multiple matching files:

# Copy all .log files
Copy-Item -Path 'C:\Logs\*.log' -Destination 'C:\Backup\'

# Copy files matching a date pattern
Copy-Item -Path 'C:\Logs\2026-05-*.log' -Destination 'C:\Backup\May2026\'

# Copy specific extensions using pipeline
Get-ChildItem 'C:\Projects\WebApp' -Filter '*.config' |
    Copy-Item -Destination 'C:\Backup\Configs\'
# All matching files copied to C:\Backup\

Error Handling When Source Is Missing

Scripts should handle missing source files gracefully rather than crashing:

$sourcePath = 'C:\Logs\missing.log'
$destPath   = 'C:\Backup\'

try {
    if (Test-Path $sourcePath) {
        Copy-Item -Path $sourcePath -Destination $destPath -ErrorAction Stop
        Write-Output "Backed up: $sourcePath"
    } else {
        Write-Warning "Source not found: $sourcePath"
    }
} catch {
    Write-Error "Copy failed: $($_.Exception.Message)"
}

# Robust backup function
function Backup-File {
    param(
        [string] $Source,
        [string] $Destination
    )
    if (-not (Test-Path $Source)) {
        Write-Warning "Skipping (not found): $Source"
        return
    }
    $destDir = Split-Path $Destination -Parent
    if (-not (Test-Path $destDir)) {
        New-Item -ItemType Directory -Path $destDir -Force | Out-Null
    }
    Copy-Item -Path $Source -Destination $Destination -Force
    Write-Output "Backed up: $(Split-Path $Source -Leaf)"
}

Common Errors and Fixes

  • Destination folder must exist unless using -Force with -Recurse: Copying a file to a non-existent folder path without -Force creates a file named after the folder, not a file inside it. Always ensure the destination directory exists first with New-Item -ItemType Directory -Force.
  • Move-Item fails on cross-drive moves without -Force: When moving between drives (e.g., C: to D:), some configurations require -Force. If a cross-drive move fails, try adding -Force, or manually Copy-Item then Remove-Item the source.

Related Cmdlets / See Also

Wrapping Up

Copy-Item and Move-Item handle all file and folder copy/move operations in PowerShell. Use -Recurse for directories, -Force to overwrite, and -WhatIf to preview before running destructive operations. Wrap critical copies in try/catch with Test-Path guards for production scripts. Your next step: build an automated daily backup script that copies your most important folders to a backup location.

Send-Item -To