How To Overwrite Files But Keep Original Files Timestamps

I have one folder "destination" where I have files and their time stamps (created, modified) I would like to preserve when I overwrite a few of those files with updated version of those files.

example

Destination Folder 
File.mp4- Created 01/01/01 (size 500mb)

Source Folder 
File.nmp4 - Created 12/12/12 (size 4.00gb)

Open in new window

I overwrite the file in the Destination folder with the new updated version from the Source Folder but keeping the original file in the destination folder timestamps

End Result (new overwrite file in the destination folder with original file timestamps)

Destination Folder
File.mp4 - Created 01/01/01 (size 4.00gb)

Open in new window


I have written a batch file to move the file as so

 
robocopy "Source" "Destination" /E

Open in new window


and this handles my overwrites and moving of my files perfectly, but I haven't found a way to preserves timestamps. I am looking for command-line so I can implement it in a batch file. Any help will be appreciated. I been reading flags for robocopy etc but maybe I'm reading it wrong or something but I haven't figured it out yet.
Chris LopezAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
With this script I pretend to replace robocopy:
https://gallery.technet.microsoft.com/scriptcenter/Copy-Files-from-folderA-to-29710ef9

It does the copy of the files and also preserves the date.

The MAGIC is in this function:
function Set-DateAttributes{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath,
        [Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$true)][switch]$folder
    )
    BEGIN{
        [int]$logcounter=0
    }
    PROCESS{
        if(!($folder)){
            [System.IO.FileInfo] $fi = New-Object System.IO.FileInfo -ArgumentList $originalFilePAth
            [System.IO.File]::SetCreationTime($targetFilePath,$fi.CreationTime)
            [System.IO.File]::SetLastWriteTime($TargetFilePath,$fi.LastWriteTime)
            [System.IO.File]::SetLastAccessTime( $TargetFilePath,$fi.LastAccessTime)
        }
        else{
            [System.IO.DirectoryInfo]$di = New-Object System.IO.DirectoryInfo -ArgumentList $OriginalFilePath
            [System.IO.Directory]::SetCreationTime($TargetFilePath,$di.CreationTime)
            [System.IO.Directory]::SetLastWriteTime($TargetFilePath,$di.LastWriteTime)
            [System.IO.Directory]::SetLastAccessTime($TargetFilePath,$di.LastAccessTime)
        }
    }
    END{
        
    }
}

Open in new window

0
Chris LopezAuthor Commented:
IM very inexperienced with powershell when it come to complex things so IDK if im running it wrong or what cause I cant even get it to move a file, let alone preserve the target file timestamps.

I created two .ps1 placed em both in the same folder one with the function you shared here and named it CopyNsetDates.ps1 and the other go.ps1 and in the go is this.

.\CopyNsetDates.ps1 -source "source" -target "target"

Open in new window


I run it but I get nothing in return.

And just to clarify this will take the target files (the files that are gonna be overwritten on) store their dates etc and then we overwrite those files with the new files and then rewrite the dates to the new files?

reason I ask cause I got a lil confused while reading this "Able to copy the files from one folder to another one and preserver the dates of the original files (Folders and Files)" because I am not trying to preserve any of the files that are being copied to the destination I am trying to preserve the files timestamps of the files in the target that are gonna be getting written over with these new versions we are moving to the destination/target folder.
0
Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
Ok, nothing happened because you need to give them the "path" where the files lie:
ex: C:\here\is\my\source\file.txt, you need to give as the source this: "C:\here\is\my\source" same as the target
The target will be the path where you want to be copied from...

so D:\here
will start copying D:\here\file.txt so the target is : "D:\here"
0
Webinar: What were the top threats in Q2 2018?

Every quarter, the WatchGuard Threat Lab releases an Internet Security Report that describes and analyzes the top threat trends impacting companies around the world. Are you ready to learn more about the top threats of Q2 2018? Register for our Sept. 26th webinar to learn more!

Chris LopezAuthor Commented:
lol im not that inexpereienced. I just wrote source their but I had my source and target path set. heres the actual way it out.

.\CopyNsetDates.ps1 -source "C:\Users\Home\Documents\NEW" -target "C:\Users\Home\Documents\OLD" 

Open in new window


is how i had it.
0
Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
Looks good, so did you run that and you will get everything under \NEW into the \OLD
0
Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
you want to copy New into Old and preserve the timestamp of the Old:

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true,Position=0)]$source,
    [Parameter(Mandatory=$true,Position=1)]$target,
    [Parameter(Mandatory=$false,position=2)][ValidateRange(1,1000000)][int]$Nfiles=10
)
#GLOBALs 
$global:ScriptLocation = $(get-location).Path
$global:DefaultLog = "$global:ScriptLocation\copy.log"
[int]$GLOBAL:Unicount=0 #variable to count operations with files

[int]$GLOBAL:FilesCopied=0 #variable to determine the files that have been copied
[int]$GLOBAL:FilesExisting=0   #variable to determine the existing files
[int]$GLOBAL:TotalDirectories=0  #variable to determine the number of directories created

#region Functions
function Write-Log{
    [CmdletBinding()]
    #[Alias('wl')]
    [OutputType([int])]
    Param(
            # The string to be written to the log.
            [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [Alias("LogContent")] [string]$Message,
            # The path to the log file.
            [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true,Position=1)] [Alias('LogPath')] [string]$Path=$global:DefaultLog,
            [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true,Position=2)] [ValidateSet("Error","Warn","Info","Load","Execute")] [string]$Level="Info",
            [Parameter(Mandatory=$false)] [switch]$NoClobber
    )

     Process{
        
        if ((Test-Path $Path) -AND $NoClobber) {
            Write-Warning "Log file $Path already exists, and you specified NoClobber. Either delete the file or specify a different name."
            Return
            }

        # If attempting to write to a log file in a folder/path that doesn't exist
        # to create the file include path.
        elseif (!(Test-Path $Path)) {
            Write-Verbose "Creating $Path."
            $NewLogFile = New-Item $Path -Force -ItemType File
            }

        else {
            # Nothing to see here yet.
            }

        # Now do the logging and additional output based on $Level
        switch ($Level) {
            'Error' {
                Write-Warning $Message
                Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") ERROR: `t $Message" | Out-File -FilePath $Path -Append
                }
            'Warn' {
                Write-Warning $Message
                Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") WARNING: `t $Message" | Out-File -FilePath $Path -Append
                }
            'Info' {
                Write-Host $Message -ForegroundColor Green
                Write-Verbose $Message
                Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") INFO: `t $Message" | Out-File -FilePath $Path -Append
                }
            'Load' {
                Write-Host $Message -ForegroundColor Magenta
                Write-Verbose $Message
                Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") LOAD: `t $Message" | Out-File -FilePath $Path -Append
                }
            'Execute' {
                Write-Host $Message -ForegroundColor Green
                Write-Verbose $Message
                Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") EXEC: `t $Message" | Out-File -FilePath $Path -Append
                }
            }
    }
}
function Copy-Info{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,mandatory=$true)] [string]$sourceDir,
        [Parameter(Position=1,mandatory=$true)] [string]$targetDir,
        [Parameter(Position=2,mandatory=$false)] [switch]$NTFS=$false
    )
    BEGIN{
        [int]$counter=0;
        [int]$LogCounter=0;
        [bool]$IsMultipleOfNFiles=$false

        if(! [System.IO.Directory]::Exists($targetDir) ){
           [System.IO.Directory]::CreateDirectory($targetDir) | Out-Null
            Set-DateAttributes -OriginalFilePath $sourceDir -TargetFilePath $targetDir -folder
            #add 1 directory to the total
            $GLOBAL:TotalDirectories++
            Write-Log -Level Load -Message "Folder ""$targetDir"" created..."
        }
    }
    PROCESS{
        foreach($file in [System.IO.Directory]::GetFiles($sourceDir) ){
            #generalcounter
            $GLOBAL:Unicount=$GLOBAL:FilesCopied+ $GLOBAL:FilesExisting + 1;

            $FilePath=[System.IO.Path]::Combine($targetDir, [System.IO.Path]::GetFileName($file))
            $FileInfoNew = new-object System.IO.FileInfo($file)

            if( ($GLOBAL:Unicount)%$Nfiles -eq 0  ){
                $IsMultipleOfNFiles = $true
            }
            else{
                $IsMultipleOfNFiles = $false
            }

            if(![System.IO.File]::Exists($FilePath) ){ #IF doesn't exists, add to the copiedfiles copy the file and set attributes
                [System.IO.File]::Copy($file, $FilePath)
                Set-DateAttributes -OriginalFilePath $file -TargetFilePath $FilePath
                $GLOBAL:FilesCopied++
            }
            else{
                #if the file exits, then get the information
			    $FileInfoExisting = new-object System.IO.FileInfo($FilePath)
                #remove the file
                Remove-item $FileInfoExisting
                #copy the new file
                [System.IO.File]::Copy($file, $FilePath)
                #set atributes from the 1st step
                Set-DateAttributesSourceFi -OriginalFilePath $FileInfoExisting -TargetFilePath $FilePath
                $GLOBAL:FilesExisting++
            }

            if($IsMultipleOfNFiles){
                Write-Log -Level Info -Message "Writing ""$FilePath""`tCreatedDirectories:$GLOBAL:TotalDirectories`tCopied:$GLOBAL:FilesCopied`tExisting:$GLOBAL:FilesExisting"
            }
        }
        #if ntfs parameter is given then assign the privilegies from Sourcedir to TargetDir
        if($NTFS){
            Copy-Privilegies -OFolder $sourceDir -TFolder $targetDir
        }

        foreach($dir in [System.IO.Directory]::GetDirectories($sourceDir) ){
            $test = [System.IO.Path]::Combine($targetDir, (New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $dir).Name)
            Copy-Info -sourceDir $dir -targetDir $test
            Set-DateAttributes -OriginalFilePath $dir -TargetFilePath $test -folder
            #GetandSetACL -OriginalFilePath $dir -TargetFilePath $test
        }
    }
    END{}
    

    #get source files
    
 }

function Set-DateAttributes{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath,
        [Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$true)][switch]$folder
    )
    BEGIN{
        [int]$logcounter=0
    }
    PROCESS{
        if(!($folder)){
            [System.IO.FileInfo] $fi = New-Object System.IO.FileInfo -ArgumentList $originalFilePAth
            [System.IO.File]::SetCreationTime($targetFilePath,$fi.CreationTime)
            [System.IO.File]::SetLastWriteTime($TargetFilePath,$fi.LastWriteTime)
            [System.IO.File]::SetLastAccessTime( $TargetFilePath,$fi.LastAccessTime)
        }
        else{
            [System.IO.DirectoryInfo]$di = New-Object System.IO.DirectoryInfo -ArgumentList $OriginalFilePath
            [System.IO.Directory]::SetCreationTime($TargetFilePath,$di.CreationTime)
            [System.IO.Directory]::SetLastWriteTime($TargetFilePath,$di.LastWriteTime)
            [System.IO.Directory]::SetLastAccessTime($TargetFilePath,$di.LastAccessTime)
        }
    }
    END{
        
    }
}
function Set-DateAttributesSourceFi{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath,
        [Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$true)][switch]$folder
    )
    BEGIN{
        [int]$logcounter=0
    }
    PROCESS{
        if(!($folder)){
            
            [System.IO.File]::SetCreationTime($targetFilePath,$OriginalFilePath.CreationTime)
            [System.IO.File]::SetLastWriteTime($TargetFilePath,$OriginalFilePath.LastWriteTime)
            [System.IO.File]::SetLastAccessTime( $TargetFilePath,$OriginalFilePath.LastAccessTime)
        }
        else{
            [System.IO.DirectoryInfo]$di = New-Object System.IO.DirectoryInfo -ArgumentList $OriginalFilePath
            [System.IO.Directory]::SetCreationTime($TargetFilePath,$di.CreationTime)
            [System.IO.Directory]::SetLastWriteTime($TargetFilePath,$di.LastWriteTime)
            [System.IO.Directory]::SetLastAccessTime($TargetFilePath,$di.LastAccessTime)
        }
    }
    END{
        
    }
}
#endregion


#$FilesOnTarget = Get-ChildItem -Recurse -File -Path $target
#$FilesOnSource = Get-ChildItem -Recurse -File -Path $source
Copy-Info -sourceDir $source -targetDir $target

Write-Log -Level Info -Message "CreatedDirectories:$GLOBAL:TotalDirectories`tCopied:$GLOBAL:FilesCopied`tExisting:$GLOBAL:FilesExisting"

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Chris LopezAuthor Commented:
Big help thanks would have been impossible on my own no matter how many tabs I open lol.
1
Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
Glad to help
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.