0

I have a script I run from Windows Powershell and it can update a files modified, and last accessed timestamps. I run the script from a Windows 7 laptop but it can update file timestamps that reside on an ext4 filesystem on a network attached USB drive formatted as ext4.

Here is the script...

$filePath = "D:\Computing\Powershell\datetest\1TB_1.csv"

$csv = Import-Csv -Path $filePath #-Delimiter "`t"

foreach($row in $csv) { "Path = $($row.FullName) and Create_TS = $($row.CreatedDateUtc) and Modified_TS = $($row.ModifiedDateUtc) and Accessed_TS = $($row.AccessedDateUtc)" $item = Get-Item $($row.FullName) $item.CreationTimeUtc = $(Get-Date $($row.CreatedDateUtc)) $item.LastWriteTimeUtc = $(Get-Date $($row.ModifiedDateUtc)) $item.LastAccessTimeUtc = $(Get-Date $($row.AccessedDateUtc)) }

The .csv contains four columns: File Path; Create_timestamp; Modified_timestamp; LastAccessed_timestamp When I run the above script it updates the timestamps of files in the specified file path with the timestamps in that rows corresponding timestamp cells.

From testing it seems to work however I just realized that trying to update a Create_timestamp for these files doesn't take the Create_timestamp value in the .csv file but instead it will become the earlier of the modified and accessed timestamps from the .csv file

Is this just how it is with files on ext4 file systems or is there a way to update their create timestamps?

muru
  • 72,889

2 Answers2

1

Setting the crtime (create time) for files in Linux is a very non-trivial task and requires filesystem debugging.

I wrote a solution for this earlier: Copying or restoring crtime for files/directories on ext4fs filesystem

I'm not sure how you've manage to mount read write an ext4fs partition under Windows, I presume you've accomplished it using ext2fsd, in which case unfortunately you're out of luck since the debugfs application is only available for Linux. You might want to compile it for Windows using e.g. mingw but it's a very non-trivial task because Windows has a different API to access block devices directly.

Edit:

on a network attached USB drive formatted as ext4.

Sorry, there's just no way to set crtime for files in this case.

  • 2
    The OP said the ext4 filesystem is shared over the network, which probably means a Linux system is sharing it using Samba or similar. But if there is no way to manipulate the creation time in Linux by any means other than filesystem debugging, it means there is no API Samba could use to change it either. – telcoM Jun 29 '20 at 07:40
  • @Artem S. Tashkinov Using ls -il and a Powershell script I have a .csv file with the inode number, file path and original timestamps for each file whose timestamps are going to change and I will need to correct. Can your script be modified to work with a .csv file as source? E.g: For each Row in .csv file update create_timestamp in ext4 filesystem where inode = inode_num and create_timestamp = create_timestamp from .csv file? Cheers! – FlexMcMurphy Jun 29 '20 at 09:08
  • 1
    @FlexMcMurphy This script can only be run for a locally mounted partition. And it requires Linux unless you are able to compile debugfs for Windows. – Artem S. Tashkinov Jun 29 '20 at 09:32
  • 1
    I connected the USB drive to a Pi running Raspbian OS. I can see the timestamps when I run debugfs stat with something like: debugfs -R "stat "/movie3/test2.txt"" /dev/sdc1 2>/dev/null and can also update them as you did in your script using debugfs -w /dev/sdc1 -R "set_inode_field "/movie3/test2.txt" crtime_lo 0x5ED0FD51". However, as @telcoM spotted, I am viewing the files in a Windows OS using a Samba share and Samba can't see the crtime timestamp value anyway. Instead the Created timestamp I see in Windows is always the earlier of the modified and accessed timestamps. So I'll forget it – FlexMcMurphy Jun 29 '20 at 11:51
0

You can use PowerScript to invoke SharpExt4 .Net library to modify the Linux file timestamp.

Use .Net Code (C#) and DLLs in Powershell

C# Sample code:

...
//Open a Linux ext4 disk assume your SD card/USB is physical disk 1
var disk = ExtDisk.Open(1);
//Get the file system
var fs = ExtFileSystem.Open(disk.Parititions[0]);
//Check file exists
if(fs.FileExists("/etc/hosts"))
{
    fs.SetCreationTime("/etc/hosts", DateTime,Now);
}
...
Nick
  • 1