2

Я хочу переместить папку (содержащую много подпапок и файлов) с одного диска 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 "swapping".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 по умолчанию изменяет время последнего доступа во время этого процесса, и ТАКЖЕ ссылается на это новое время последнего доступа, чтобы создать новое время создания папки в ее новом расположении (она НЕ ссылается на первоначальное время создания совершенно очевидно). То есть, если вы попытаетесь установить новое время создания равным первоначальному времени создания, ничего не получится, потому что новое время последнего доступа по умолчанию автоматически изменит новое время создания, чтобы оно равнялось ему. Таким образом, если вы заставите 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 }
}

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

1 ответ1

1

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

Таким образом, ваша цель - обеспечить, чтобы файлы и папки, перемещенные из исходного местоположения в местоположение назначения, имели свои 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
       }
    }

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .