How to NOT overwrite existing files

Currently, I'm using Copy-Item and wondering if there's a simple command that will only copy files that don't exist or are new files by date/time. Looked online but everything I see seems to be using -WhatIf command. Also, seen -Recurse being used. I don't fully understand what that command does either. Any ideas?

$From = "E:\Folder\*"
$To = "\\Server\Folder"
Copy-Item -Path $From -Destination $To -Verbose
3

3 Answers

Again, what you are after is easily accomplished with RoboCopy.exe, and this question has been asked here and many other Q&A sites, multiple times. even here on SU.

Robocopy to copy only new folders and files

As well as on SO

RC will only copy newer files. Files of the same age will be skipped.
C:\SourceFolder D:\DestinationFolder ABC.dll /XO
robocopy c:\users\valery\documents j:\robocopy /XO /E /MAXAGE:20131030 /XD
# Result: A full folders tree is created. Only new files copied.

So, your question is really a duplicate of the above.

Otherwise, you end up having to know and do stuff like the below(and if you are new, as you say, it's not easy to find in a single search or set of searches):

Clear-Host
$Source = 'D:\Temp\Source'
$Destination = 'D:\Temp\Destination'
Get-ChildItem -Path $Source -Recurse |
ForEach-Object { If (Test-Path -Path "$Destination\$($PSItem.Name)") { Write-Warning -Message "`n$($PSItem.Name) already exists in $Destination. Checking timestamp`n" Try { "Copying file if $($PSItem.Name) is newer" Get-ChildItem -Path $Destination -Filter $PSItem.Name | Where-Object LastWriteTime -lt $PSItem.LastWriteTime -ErrorAction Stop Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf } Catch {$PSItem.Exception.Message} } Else { Write-Host "`n$PSItem.Name does not Exist in $Destination`n" -ForegroundColor Cyan Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf }
}
# Results
<#
...
WARNING:
abc.txt already exists in D:\Temp\Destination. Checking timestamp
...
WARNING:
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp
Copying file if $($PSItem.Name) is newer
-a---- 10-Apr-21 00:00 0 LexPointOh.txt
What if: Performing the operation
"Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt
Destination: D:\Temp\Destination\LexPointOh.txt".
mytest - Copy.txt.Name does not Exist in D:\Temp\Destination
What if: Performing the operation "Copy File" on target
"Item: D:\Temp\Source\mytest - Copy.txt
Destination: D:\Temp\Destination\mytest - Copy.txt".
...
#>

Just remove the -WhatIf for it to do stuff.

So, based on your statement:

I don't fully understand what that command does either.

That being the case; then, what I show above would be more of a challenge. Hence why I pointed you to the help files (training site, Youtube, etc.) in my original post.

The above is just one way to do this. PowerShell provides various ways to do X or Y things. For example, here is another way of doing the same use case.

Clear-Host
$Source = ($SourceFiles = Get-ChildItem -Path 'D:\Temp\Source')[0].DirectoryName
$Destination = ($DestinationFiles = Get-ChildItem -Path 'D:\Temp\Destination')[0].DirectoryName
Compare-Object -ReferenceObject $SourceFiles -DifferenceObject $DestinationFiles -IncludeEqual |
ForEach-Object { If ($PSItem.SideIndicator -match '==|=>') { If ( Get-ChildItem -Path $Destination -Filter $($PSItem.InputObject.Name) | Where-Object LastWriteTime -LT $PSItem.InputObject.LastWriteTime ) { Write-Warning -Message "`n$($PSItem.InputObject) already exists in $Destination. Checking timestamp`n" Copy-Item -Path $PSItem.InputObject.FullName -Destination $Destination -ErrorAction SilentlyContinue -Verbose -WhatIf } } Else { Write-Host "`n$($PSItem.InputObject ) does not Exist in $Destination`n" -ForegroundColor Cyan Copy-Item -Path $PSItem.InputObject.FullName -Destination $Destination -Verbose -WhatIf }
}
# Results
<#
WARNING:
abc.txt already exists in D:\Temp\Destination. Checking timestamp
What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\abc.txt Destination: D:\Temp\Destination\abc.txt".
WARNING:
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp
What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt Destination: D:\Temp\Destination\LexPointOh.txt".
mytest - Copy.txt does not Exist in D:\Temp\Destination
What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\mytest - Copy.txt Destination: D:\Temp\Destination\mytest - Copy.txt".
...
#>

Yet, any time you are using comparative logic, you are not looking at simple command, in most cases.

So, use the right tool for the job. Unless this is a homework assignment, don't increase your core workload/Don't reinvent the wheel.

2

You can make use of the cmdlet Get-ChildItem. Your script should basically have this flow:

  1. Check if the file exists on the destination folder
  2. If exists, then skip
  3. If not exist, then copy

I ran a very crude and simple test on my computer and this should work (remember to modify it to your use-case)

$FROM = "T:\Files\Scripts1\BackItUp.ps1"
$TO = "T:\Files2"
if (Get-ChildItem -Path $TO "BackItUp.ps1") { Write-Host "file already exists..skipping"
} else { Copy-Item $FROM -Destination $TO
}
4

From Stack Overflow:

Copy-Item (Join-Path $dir_from "*") $dir_to -Exclude (Get-ChildItem $dir_to)

Link: Why is Copy-Item overwriting destination files by default?

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like