1

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 Answers3

2

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

https://stackoverflow.com/questions/23303532/use-robocopy-to-copy-only-changed-files

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 timestampn"

    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 timestampn"
Copy-Item -Path $PSItem.InputObject.FullName -Destination $Destination -ErrorAction SilentlyContinue -Verbose -WhatIf } } Else { Write-Host "n$($PSItem.InputObject ) does not Exist in $Destinationn" -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.

postanote
  • 5,136
1

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 }

0

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?