Как сохранить метки времени для всех папок при перемещении их с одного диска NTFS на другой?

395
Devon Heath

Я хочу переместить папку (содержащую много подпапок и файлов) с одного диска NTFS на другой.

Наблюдение: я заметил, что при этом метки времени («дата создания», «дата последнего изменения» и т. Д.) Не сохраняются в папках, содержащих хотя бы одну папку / файл. Даже перемещенные пустые папки в конечном итоге «автоматически» изменят дату своего создания, чтобы соответствовать остальным (как только вы поместите что-то в эту пустую папку на новом диске).

Мои усилия: я перепробовал почти все, что смог найти в Google по этому вопросу (Robocopy, Richcopy, Microsoft SyncToy, Total Commander, Free Commander ... и многие, многие другие ...) - все они производят относительно одинаково Результаты. Ничто не привело к всеобъемлющему, 100% сохранению перемещаемого источника. Робокопия и Ричкопи (вместе с «Командирами») близки, но у меня все еще возникают проблемы (во всех случаях), когда дата создания неправильно «сохраняется», дата последнего изменения не может быть сохранена вообще и т. Д. Единственное истинное обещание Я видел за этим ... это Пауэршелл.


Мое путешествие PowerShell

Я наткнулся на эту ссылку:

https://stackoverflow.com/questions/34951911/powershell-move-item-folder-time-stamp

... с помощью этого скрипта:

function Move-FileWithTimestamp { [cmdletbinding()] param( [Parameter(Mandatory=$true,Position=0)][string]$Path, [Parameter(Mandatory=$true,Position=1)][string]$Destination )  $origLastAccessTime = ( Get-Item $Path ).LastAccessTime $fileName = ( Get-Item $Path ).Name Move-Item -Path $Path -Destination $Destination $(Get-Item ($Destination+'\'+$fileName)).LastAccessTime =  $origLastAccessTime } 

Сценарий в приведенной выше ветке все еще не работал по-другому, чем программы, которые я перечислил, но, по крайней мере, здесь у меня была платформа, на которой я мог бы изменить / настроить / настроить некоторые вещи для своих конкретных нужд. Поэтому я сделал все, что мог, имея свои ограниченные знания в этой области (то есть изменив «.LastAccessTime» на «.CreationTime», поменяв местами «.LastAccessTime» на «LastWriteTime» и т. Д.), И в конце концов приблизился к сохранению всех меток времени ( Я считаю, что в какой-то момент я сохранил последнее изменение, последний доступ и последнее сохранение в моей тестовой папке). Тем не менее, я все еще не могу правильно сохранить дату создания, и то, что я смог сделать со всем остальным, очевидно, применимо только к одиночной тестовой папке (и ничего больше, например, к подпапкам внутри нее ... но это только потому, что я не

Я зациклен на этом, когда дело доходит до этого, поэтому мне интересно, хочет ли кто-нибудь там заняться этим.

ОБНОВЛЕНИЕ: вот где я сейчас нахожусь:

function Move-FileWithTimestamp { [cmdletbinding()] param( [Parameter(Mandatory=$true,Position=0)][string]$Path, [Parameter(Mandatory=$true,Position=1)][string]$Destination ) $origCreationTime = ( Get-Item $Path ).CreationTime $origLastWriteTime = ( Get-Item $Path ).LastWriteTime $origLastAccessTime = ( Get-Item $Path ).CreationTime  $fileName = ( Get-Item $Path ).Name Move-Item -Path $Path -Destination $Destination $(Get-Item ($Destination+'\'+$fileName)).CreationTime = $origCreationTime $(Get-Item ($Destination+'\'+$fileName)).LastWriteTime =  $origLastWriteTime $(Get-Item ($Destination+'\'+$fileName)).LastAccessTime =  $origLastAccessTime } 

Похоже, что это сохраняет первоначальное время создания для главной перемещаемой папки (а также время последнего изменения / записи), но очевидно, что время последнего доступа изменяется на время создания оригинала в процессе (кажется, что когда папка При перемещении на новый диск Windows по умолчанию изменяет время последнего доступа во время этого процесса, и ТАКЖЕ ссылается на это новое время последнего доступа, чтобы создать новое время создания папки в ее новом расположении (она НЕ ссылается на первоначальное время создания вообще не имеет значения) IE, если вы попытаетесь установить новое время создания равным исходному времени создания, ничего не получится, потому что новое время последнего доступа по умолчанию автоматически изменит новое время создания, чтобы оно равнялось ему. вы заставляете Windows сделать новое время последнего доступа равным первоначальному времени создания,тогда вы в конечном итоге получите правильное время создания, но неверное время последнего доступа.

Итак, теперь я застрял с неверным временем последнего доступа, но с правильным временем для всего остального. Кроме того, я понятия не имею, как я получу это, чтобы применить ко всем подпапкам, так что дайте мне знать, если кто-нибудь знает, как это сделать.

ОБНОВИТЬ:

function Move-FileWithTimestamp { [cmdletbinding()] param( [Parameter(Mandatory=$true,Position=0)][string]$Path, [Parameter(Mandatory=$true,Position=1)][string]$Destination ) $origCreationTime = ( Get-Item $Path ).CreationTime $origLastWriteTime = ( Get-Item $Path ).LastWriteTime $origLastAccessTime = ( Get-Item $Path ).CreationTime $origChildCreationTime = ( Get-ChildItem $Path ).CreationTime $origChildLastWriteTime = ( Get-ChildItem $Path ).LastWriteTime $origChildLastAccessTime = ( Get-ChildItem $Path ).CreationTime   $fileName = ( Get-Item $Path ).Name Move-Item -Path $Path -Destination $Destination $(Get-Item ($Destination+'\'+$fileName)).CreationTime = $origCreationTime $(Get-Item ($Destination+'\'+$fileName)).LastWriteTime = $origLastWriteTime $(Get-Item ($Destination+'\'+$fileName)).LastAccessTime =  $origLastAccessTime $(Get-ChildItem ($Destination+'\'+$fileName)) | ForEach-Object {  $_.CreationTime = $origChildCreationTime } $(Get-ChildItem ($Destination+'\'+$fileName)) | ForEach-Object {  $_.LastWriteTime = $origChildLastWriteTime } $(Get-ChildItem ($Destination+'\'+$fileName)) | ForEach-Object {  $_.LastAccessTime = $origChildLastAccessTime } } 

Теперь у меня есть основная папка и одна, если это подпапки с правильным созданием и датами последнего изменения (но не последний доступ). Я понятия не имею, как сделать это для остальных подпапок в главной папке, а также для любых подпапок в этих подпапках.

2
Вы говорите мне, что «Robocopy / copyall» не работает? Appleoddity 6 лет назад 0
Скопировано, чтобы комментировать для OP: Нет. Robocopy не сохраняет для меня 3 основных метки времени для папок (созданных, последних измененных и последних посещенных). Я уже попробовал все переключатели. Я определенно думаю, что есть способ сделать это с помощью Powershell ... Я просто слишком незнаком с кодированием и написанием сценариев ... поэтому я надеюсь, что кто-то там может взглянуть и выглядеть так: "О, это просто ". fixer1234 6 лет назад 0

1 ответ на вопрос

1
Pimp Juice IT

Переместить дерево каталогов и сохранить все значения атрибутов отметок времени

Таким образом, ваша цель состоит в том, чтобы гарантировать, что файлы и папки, которые перемещаются из исходного местоположения через к месту назначения имеют свои LastWriteTime, LastAccessTimeи CreationTimeзначение, сохраненное от местоположения источника, где те возник атрибут.

По сути это., ,

  • Использует Copy-Item, а неMove-Item
  • Перебирает источник и устанавливает значения переменных атрибута timestamp, чтобы затем использовать Set-ItemProperty, чтобы рекурсивно установить те же значения для этих свойств в месте назначения для всех папок и файлов.
  • Явно выполняет тот же цикл установки значения атрибута временной метки Set-ItemProperty только для объектов папки
  • Использует Remove-Item, чтобы затем удалить исходные объекты исходного файла, только очистив их
  • Использует Remove-Item, чтобы затем удалить исходный объект исходной папки, только очистив их

скрипт

$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 } } 

Дополнительные ресурсы

Комментарии не для расширенного обсуждения; этот разговор был [перемещен в чат] (https://chat.stackexchange.com/rooms/84436/discussion-on-answer-by-pimp-juice-it-how-to-preserve-timestamps-for-all- папки). DavidPostill 6 лет назад 0
@DavidPostill Можете ли вы дать мне ссылку, чтобы прочитать, как я могу это сделать? Я всегда получаю длинные комментарии и никогда не получаю ссылку, чтобы сделать чат настолько любопытным, если бы был какой-то способ чтения, я сам могу научиться переносить их в чат, чтобы моды не были помечены и тому подобное. Pimp Juice IT 6 лет назад 0
AFAIK только моды могут сделать это. DavidPostill 6 лет назад 1