Avatar of Robert Berke
Robert Berke
Flag for United States of America asked on

Created an "empty" Server 2016 domain. How to "fill it" with old server data and retain original last modification date on all folders.

It is time to replace our incredibly simple sbs2003 domain with a virtualized windows server essentials 2016 domain. It is just a file server for a dozen windows 10 clients.  No exchange, sql or other complications.

The new WSEServer  environment uses shadowprotect SPX 6.5.3 for daily backups.

The old sbs2003 used shadowprotect 3, but I believe we could also run SPX 6.4.3 on the old machine which might help solve my problem.

 

We have tested the following:

Step 1 created an "empty" Server04 machine with 10 users and internet connectivity. (\\Server04 is the hypervisor, and \\WSEServer is the virtual fileserver.)

Step 2 use Robocopy to copy old server d:\data\OfficeFolders\ to a USB

Step 3 use robocopy to copy USB to \\WSSERVER\data\OfficeFolders

The test worked very well, except all 10,000 folders now have last date modified as 11/3/2017. Luckily, the file level date is correct so 300,000 files all look fine.

For reasons that are too complicated to explain, losing the folder level dates is a big deal for us. We can live with it, but it will irritate me daily for the next 3 years.

Does anybody have any suggestions?  We tried restoring the SBS 2003 shadow protect 3.0 backups for our restore, but the SIDs caused a bunch of access denied problems.  We tried taking ownership of the USB folders and lower levels, but that step alone ran for about 3 hours. We then tried to restore again, and things went even further downhill.


Does anybody have any ideas?

For instance, if Shadow Protect BACKUP had an option for dropping SIDs that would be great, but I cannot see such an option. Another possibility would be a RESTORE that would automatically drop the SIDS, but that seems even less likely to be possible.
Or possibly a routine that will copy the date mod field and zap the folders after they were restored.  

Maybe powershell to the rescue?

rberke
Windows Server 2016Storage Software

Avatar of undefined
Last Comment
Jose Gabriel Ortega Castro

8/22/2022 - Mon
NVIT

With robocopy, use the /dcopy:t switch to keep the original source folder dates
Dariusz Tyka

Robocopy and the '/dcopy:t' switch will allow you to retain folder datestamp.
Jose Gabriel Ortega Castro

Well you just need the logic to reset those dates in the files I've prepared a function for you and how to use it.

The only thing you need now is to get the Files recursively

function Set-DateAttributes{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath
    )
    BEGIN{
        
    }
    PROCESS{
        [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)

    }
    END{}
}

Set-DateAttributes -OriginalFilePath "D:\CloudOD\OneDrive\Soporte Curriculum\Taller-Big-Data.pdf" -TargetFilePath "D:\Cloud\Dropbox\Desktop\123\Taller-Big-Data.pdf"

Open in new window


so once you get the files you provide the Source and destination to the function and it will make the threat.
Your help has saved me hundreds of hours of internet surfing.
fblack61
Robert Berke

ASKER
/dcopy is not available on sbs2003.  

Nonetheless, I tested several variations of the following on windows 10.  It created folders with today's date.

robocopy "s:\arobotest" "g:\robousb"  /e /dcopy:t

I have not had time to try the powershell solution yet, mainly because I am very weak in powershell and making it recursive might be tricky.
Jose Gabriel Ortega Castro

Ok let me finish my answer with that part.
Jose Gabriel Ortega Castro

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true,Position=0)]$source,
    [Parameter(Mandatory=$true,Position=1)]$target

)

function CopyInfo{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,mandatory=$true)] [string]$sourceDir,
        [Parameter(Position=1,mandatory=$true)] [string]$targetDir
    )

    if(! [System.IO.Directory]::Exists($targetDir) ){
        [System.IO.Directory]::CreateDirectory($targetDir) | Out-Null
    }

    #get source files
    foreach($file in [System.IO.Directory]::GetFiles($sourceDir) ){
            $FilePath=[System.IO.Path]::Combine($targetDir, [System.IO.Path]::GetFileName($file))
            $FileInfoNew      = new-object System.IO.FileInfo($file)

            if(![System.IO.File]::Exists($FilePath) ){
                #Write-Output "Writing $file"
                [System.IO.File]::Copy($file, $FilePath)
                Set-DateAttributes -OriginalFilePath $file -TargetFilePath $FilePath
            }
            else{
				$FileInfoExisting = new-object System.IO.FileInfo($FilePath)
				$FileInfoNew      = new-object System.IO.FileInfo($file)
#setattributes
                Set-DateAttributes -OriginalFilePath $file -TargetFilePath $FilePath
            }
    }

    foreach($dir in [System.IO.Directory]::GetDirectories($sourceDir) ){
    $test = [System.IO.Path]::Combine($targetDir, (New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $dir).Name)
        CopyInfo -sourceDir $dir -targetDir $test
    }
 }

#Copy files from source to target


CopyInfo -sourceDir $Source -targetDir $FolderName 

function Set-DateAttributes{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath
    )
    BEGIN{
        
    }
    PROCESS{
        [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)

    }
    END{}
}

#Set-DateAttributes -OriginalFilePath "D:\CloudOD\OneDrive\Soporte Curriculum\Taller-Big-Data.pdf" -TargetFilePath "D:\Cloud\Dropbox\Desktop\123\Taller-Big-Data.pdf"
CopyInfo -sourceDir $source -targetDir $target

Open in new window


save it as a text file with extension .ps1  (ex: setterDates.ps1)
use:
.\SetterDates.ps1 -source "C:\sources\" -target "D:\Target\Folder"

Must be an elevated windows PowerShell console
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Robert Berke

ASKER
I must be doing something wrong. (My powershell skills are practically non-existent and it has been two years since I used it)

I put your program into c:\aatmp\copy.ps1, then used run as administrator to open windows 10 powershell ise (x86)

I then typed the following into command window
 Set-ExecutionPolicy RemoteSigned  
 c:\aatmp\copy.ps1 -source "C:\arobotest\" -target "c:\arobousb"

It started running and created the target directory,
then gave me a bunch of errors. The first one seems to be the most important:  
 

CopyInfo : Cannot bind argument to parameter 'targetDir' because it is an empty string.
At C:\aatmp\copy.ps1:46 char:40
+ CopyInfo -sourceDir $Source -targetDir $FolderName
.                                                                    ============  $foldername was underlined
    + CategoryInfo          : InvalidData: (:) [CopyInfo], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,CopyInf
Robert Berke

ASKER
Actually, I don't think Jose Ortega actually tested his code.

I noticed that $FolderName was never set, so I changed lined 46 to be


CopyInfo -sourceDir $Source -targetDir $Target

That got me a little closer, but the program then aborts with this another messageSet-DateAttributes : The term 'Set-DateAttributes' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\aatmp\copy.ps1:33 char:17
+                 Set-DateAttributes -OriginalFilePath $file -TargetFil ...
+                 ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Set-DateAttributes:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundExceptio


My worry is that I will spend a lot of time debugging the program, only to discover that it will not work.
Jose Gabriel Ortega Castro

Ok, let me try the code on my end. I'll answer shortly
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
Jose Gabriel Ortega Castro

Yeah, It had one unnecessary additional line in the wrong place.

Try this one:
#D:\CloudOD\OneDrive\Soporte Curriculum
#D:\Cloud\Dropbox\Desktop\destTest
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true,Position=0)]$source,
    [Parameter(Mandatory=$true,Position=1)]$target

)

function CopyInfo{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,mandatory=$true)] [string]$sourceDir,
        [Parameter(Position=1,mandatory=$true)] [string]$targetDir
    )

    if(! [System.IO.Directory]::Exists($targetDir) ){
        [System.IO.Directory]::CreateDirectory($targetDir) | Out-Null
    }

    #get source files
    foreach($file in [System.IO.Directory]::GetFiles($sourceDir) ){
            $FilePath=[System.IO.Path]::Combine($targetDir, [System.IO.Path]::GetFileName($file))
            $FileInfoNew      = new-object System.IO.FileInfo($file)

            if(![System.IO.File]::Exists($FilePath) ){
                #Write-Output "Writing $file"
                [System.IO.File]::Copy($file, $FilePath)
                Set-DateAttributes -OriginalFilePath $file -TargetFilePath $FilePath
            }
            else{
				$FileInfoExisting = new-object System.IO.FileInfo($FilePath)
				$FileInfoNew      = new-object System.IO.FileInfo($file)
#setattributes
                Set-DateAttributes -OriginalFilePath $file -TargetFilePath $FilePath
            }
    }

    foreach($dir in [System.IO.Directory]::GetDirectories($sourceDir) ){
    $test = [System.IO.Path]::Combine($targetDir, (New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $dir).Name)
        CopyInfo -sourceDir $dir -targetDir $test
    }
 }

#Copy files from source to target




function Set-DateAttributes{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]$OriginalFilePath,
        [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$TargetFilePath
    )
    BEGIN{
        
    }
    PROCESS{
        [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)

    }
    END{}
}

#Set-DateAttributes -OriginalFilePath "D:\CloudOD\OneDrive\Soporte Curriculum\Taller-Big-Data.pdf" -TargetFilePath "D:\Cloud\Dropbox\Desktop\123\Taller-Big-Data.pdf"
CopyInfo -sourceDir $source -targetDir $target

Open in new window

Robert Berke

ASKER
Just as I feared.  The folders copied, but the last modification date is today.  Exactly the same problem that I had with robocopy.

Anybody else have any bright ideas?
Robert Berke

ASKER
If someone can finds vb or powershell code that successfully zaps a folder mod date, I can do the rest of the necessary work.


I am running out of time.  This must be done by Thursday 11/9/2017 or I  will have to live with bad dates for the rest of my career.  The new server goes into production on Friday come hell or high water.

to summarize the problem:

When windows creates a folder, the modification date always shows Today's Date (the date it was created).  That is true if the files are copied with Explorer,  powershell,  robocopy, vba etc.

An unhelpful exception is when explorer drags and MOVES the folders to the SAME DISK. That is internally a rename and the date is untouched. This is unhelpful for me because I must put the files onto the USB.

To override this will require more heroic measures to zap the folder after it created.

For instance, I found code to zap a folder mod date, but, it doesnot work on windows 10, 7 or xp.  (It does work on file dates, just not folder dates)

Sub zapfolder()
               
    Dim objshell, objfolder, objfolderItem
   
    Set objshell = CreateObject("Shell.Application")
    Set objfolder = objshell.Namespace("C:\aatmp\")
    Set objfolderItem = objfolder.Items.Item("d")
    Debug.Print objfolderItem.Name
   
    objfolderItem.ModifyDate = Now() - 5 ' < ========= here is where the zap occurs ===========================
    Debug.Print objfolderItem.ModifyDate
End Sub

If someone can find similar code that successfully zaps a folder mod date, I can do the rest of the necessary work.


I would write a "create_zapdate" program to create a "zapDate" with csv records like this.
1/1/2014 15:00:00, "s:\allFolders\a\b\paul"
5/12/2014 12:33:00, "s:\allfolders\a\b\mary"
another time stamp,"s:\allfolders\a\b"

I would also write a "Apply_zapdate" program that uses the csv  to zap the USB disk.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Robert Berke

ASKER
add xcopy to the list.  Folders lose date/time for xcopy, robocopy, explorer, powershell, and many vba techniques. (there may be some that work, but I have not been able to find them)

rberke
Jose Gabriel Ortega Castro

So I modify the files within the folders. do you want that to work with the folders as well?
I didn't know that I thought it was enough with the files.
Will add the folders.
Robert Berke

ASKER
ABSOLUTLY I want the folders.  In my first post I said "Luckily, the file level date is correct so 300,000 files all look fine."

The folders are the big problem, and I would be incredibly grateful if you can solve it.

But, please test it by going TO a USB.

This is because copies to USB drives are asymmetrical:
     Going from a server to USB resets all dates to Now().  
     Going from USB to a server retains the USB's folder dates.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER CERTIFIED SOLUTION
Jose Gabriel Ortega Castro

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Robert Berke

ASKER
Hot dog it almost works !!!!   I set-executionpolicy unrestricted then ran a very smple tests that worked great.

But a slightly more complicated test had errors.  The errors cannot be too significant because the resulting folders looks exactly right, 9 files in two folders with the correct date stamp on both folders.

By the way, your public website shows you have tested on 6 versions of window INCLUDING Server 2003 !!!  That is really impressive.

Anyway, here are the first few errors:

PS C:\WINDOWS\system32>  c:\aatmp\CopyNsetDates.ps1 -source "s:\arobotest\" -target "g:\arobousb"

Writing "g:\arobousb\Thumbs.db"
The Creation,LastWrite and LastAccess times were set on the file s:\arobotest\Thumbs.db
Set-Acl : AclObject
At C:\aatmp\CopyNsetDates.ps1:184 char:9
+         Set-Acl $TargetFilePath $OriginalFilePath
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (s:\arobotest\Thumbs.db:String) [Set-Acl], ArgumentException
    + FullyQualifiedErrorId : SetAcl_AclObject,Microsoft.PowerShell.Commands.SetAclCommand
 
Writing "g:\arobousb\~$cro Instructions Template.doc"
The Creation,LastWrite and LastAccess times were set on the file s:\arobotest\~$cro Instructions Template.doc
Set-Acl : AclObject
At C:\aatmp\CopyNsetDates.ps1:184 char:9
+         Set-Acl $TargetFilePath $OriginalFilePath
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (s:\arobotest\~$...ns Template.doc:String) [Set-Acl], ArgumentException
    + FullyQualifiedErrorId : SetAcl_AclObject,Microsoft.PowerShell.Commands.SetAclCommand
 
Writing "g:\arobousb\future templates\do not use yet FCC Form 500 instructions.doc"
The Creation,LastWrite and LastAccess times were set on the file s:\arobotest\future templates\do not use yet FCC Form 500 i
nstructions.doc
Set-Acl : AclObject
At C:\aatmp\CopyNsetDates.ps1:184 char:9
+         Set-Acl $TargetFilePath $OriginalFilePath
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (s:\arobotest\fu...nstructions.doc:String) [Set-Acl], ArgumentException
    + FullyQualifiedErrorId : SetAcl_AclObject,Microsoft.PowerShell.Commands.SetAclCommand
 
Writing "g:\arobousb\future templates\do not use yet FCC Form 500 with &.dot"
The Creation,LastWrite and LastAccess times were set on the file s:\arobotest\future templates\do not use yet FCC Form 500 w
ith &.dot
Set-Acl : AclObject
At C:\aatmp\CopyNsetDates.ps1:184 char:9
+         Set-Acl $TargetFilePath $OriginalFilePath
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (s:\arobotest\fu... 500 with &.dot:String) [Set-Acl], ArgumentException
    + FullyQualifiedErrorId : SetAcl_AclObject,Microsoft.PowerShell.Commands.SetAclCommand
Robert Berke

ASKER
Thanks for your help
Jose Gabriel Ortega Castro

* The Creation,LastWrite and LastAccess times were set on the file s:\arobotest\Thumbs.db

that file is a system file and it should have been blocked so you don't have access to it.

* Writing "g:\arobousb\~$cro Instructions Template.doc"
have 2 invalids chars on windows "~$ "

* "g:\arobousb\future templates\do not use yet FCC Form 500 with &.dot"
Invalid & char on files.

* riting "g:\arobousb\future templates\do not use yet FCC Form 500 instructions.doc"

Issue while getting that attributes because the size of the characters (260 is the limit)


⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.