Preserve all timestamps when moving data from one NTFS drive to another
Move directory tree and retain all timestamp attribute values
So your goal is to ensure that files and folders that are moved from a source location over to a destination location have their LastWriteTime
, LastAccessTime
, and CreationTime
attribute values retained from the source location where those originated.
Essentially this. . .
- Uses Copy-Item rather than
Move-Item
- Loops through source and sets timestamp attribute variables values to then use Set-ItemProperty to set those same values to those properties in the destination for all folders and files recursively
- Explicitly does the same Set-ItemProperty timestamp attribute value set loop for folder objects only
- Uses Remove-Item to then delete the original source file objects only cleaning those up
- Uses Remove-Item to then delete the original source folder object only cleaning those up
Script
$src = "C:\Src\Folder\123\"
$dest = "X:\Dest\Folder\321\"
$src = $src.Replace("\","\\")
$i = Get-ChildItem -Path $src -Recurse
$i | % { ## -- All files and folders
$apath = $_.FullName -Replace $src,""
$cpath = $dest + $apath
Copy-Item -Path $_.FullName -Destination $cpath -Force
If (Test-Path $cpath)
{
Set-ItemProperty -Path $cpath -Name CreationTime -Value $_.CreationTime
Set-ItemProperty -Path $cpath -Name LastWriteTime -Value $_.LastWriteTime
Set-ItemProperty -Path $cpath -Name LastAccessTime -Value $_.LastAccessTime
}
}
$d = Get-ChildItem -Path $src -Recurse -Directory
$d | % { ## -- Folders only
$apath = $_.FullName -Replace $src,""
$cpath = $dest + $apath
If (Test-Path $cpath)
{
Set-ItemProperty -Path $cpath -Name CreationTime -Value $_.CreationTime
Set-ItemProperty -Path $cpath -Name LastWriteTime -Value $_.LastWriteTime
Set-ItemProperty -Path $cpath -Name LastAccessTime -Value $_.LastAccessTime
}
}
$f = Get-ChildItem -Path $src -Recurse -File
$f | % { ## -- Delete files only
$apath = $_.FullName -Replace $src,""
$cpath = $dest + $apath
If (Test-Path $cpath)
{
Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
}
}
$d | % { ## -- Delete directories only
$apath = $_ -Replace $src,""
$cpath = $dest + $apath
If (Test-Path $cpath)
{
Remove-Item $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
}
}
Further Resources
- Replace
- Get-ChildItem
- ForEach-Object
Standard Aliases for Foreach-Object: the '
%
' symbol, ForEach - Copy-Item
- If
- Test-Path
- Set-ItemProperty
- Remove-Item