Ok, here is the scenario. I have a folder that people can use to share data around. Quick and easy, no USB needed. However they tend to leave the data in there and it is filling up the HDD. I want to delete everything over 30 days old. I was going to do this with powershell -
$limit = (Get-Date).AddDays(-30)
$path = "C:\temp"
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -whatif
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse -whatif
I left the -whatif there because that makes it easier to test.
So I tested it, and it works fine, but during the testing I ran into a small problem. Moved files retain their original creation date. Why is this important? Because a user might move something into the folder 5 minutes before the script runs, and it will get deleted if the creation date is older than 30 days. Copying a file is no problem, it gets a new creation date when copied. Its only the moved files.
So question, how do I find the date the file was moved into the folder so that it isn't accidentally deleted?
As it turns out, there's a hidden fourth modification time in windows: ChangeTime. As far as I understand it, it's stored in a separate place, and isn't returned by the normal APIs - it's part of the Master File Table, I think. (Perhaps it depends on your file system type?) Whether that description is accurate or not, consider the following:
C:\Users\erhannis\Downloads\nsx220en>stat nsx-2.2.0
File: nsx-2.2.0
Size: 0 Blocks: 4 IO Block: 65536 directory
Device: c6194f59h/3323547481d Inode: 7318349397564576 Links: 1
Access: (0755/drwxr-xr-x) Uid: (1056947/ erhannis) Gid: (1049089/ UNKNOWN)
Access: 2016-03-24 14:41:17.880026600 -0400
Modify: 2016-03-24 14:41:17.880026600 -0400
Change: 2020-12-01 17:03:41.697541400 -0500
Birth: 2016-03-24 14:35:09.540397700 -0400
(See links for relevant programs.)
The time listed next to Change: is the time I moved the folder from one place to another. When I move a file, the Change date is updated. Note: I tried moving a folder full of files, and it appears only the root object's ChangeTime is updated. So like, for your purposes, you would consider the last ChangeTime of a given file to be the newest of the ChangeTime of the file and any parent directory. (Or, just stop recursing into directories when you hit a change time too new; depends on how you're doing it.)
Perhaps more relevantly, the Linux find command has a parameter -cmin that lets you filter by "metadata more recently changed than X". So, for instance, find -cmin -5 recursively finds all items whose metadata (e.g., when it was last moved) has changed less than five minutes ago. (find -cmin 5 would find files changed MORE than 5 minutes ago.) (On windows, I rename the find command to something else so it doesn't conflict with the default windows find command.)
Windows ports of both stat and find are available incidentally as part of a Git installation:
https://git-scm.com/download/win
There's also this Powershell script I found - haven't tried it, but it purports to get the ChangeTime of a file.
https://gallery.technet.microsoft.com/scriptcenter/Get-MFT-Timestamp-of-a-file-9227f399
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With