Last active
April 24, 2019 20:06
-
-
Save IISResetMe/0ab52974d0390ba1cbd9edb2fa477f11 to your computer and use it in GitHub Desktop.
Fast acquisition of LastWriteTime attribute value of files via Kernel32.dll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$kernel32,$filetime = Add-Type -TypeDefinition @' | |
// Partial port of the C# example at | |
// https://www.pinvoke.net/default.aspx/kernel32.getfiletime | |
// | |
using System; | |
using System.Runtime.InteropServices; | |
public class Kernel32wrappers { | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool CloseHandle(IntPtr handle); | |
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] | |
public static extern IntPtr CreateFile(string lpFileName,uint dwDesiredAccess,uint dwShareMode,IntPtr SecurityAttributes,uint dwCreationDisposition,uint dwFlagsAndAttributes,IntPtr hTemplateFile); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool GetFileTime(IntPtr hFile,ref FILETIME lpCreationTime,ref FILETIME lpLastAccessTime,ref FILETIME lpLastWriteTime); | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct FILETIME | |
{ | |
public uint dwLowDateTime; | |
public uint dwHighDateTime; | |
} | |
'@ -PassThru | |
foreach($filename in [System.IO.Directory]::EnumerateFiles($PWD)){ | |
try{ | |
$fileHandle = $kernel32::CreateFile($filename, 0, 7, [IntPtr]::Zero, 3, 0x80, [IntPtr]::Zero) | |
$creation,$access,$write = 1..3 |ForEach-Object { $filetime::new() } | |
$res = $kernel32::GetFileTime($fileHandle,[ref]$creation,[ref]$access,[ref]$write) | |
if($res) { | |
$lastWriteTime = [datetime]::FromFileTime((([long]$write.dwHighDateTime) -shl 32) + $write.dwLowDateTime) | |
} | |
else { | |
$lastWriteTime = (Get-Item -LiteralPath $filename).LastWriteTime | |
} | |
[pscustomobject]@{ | |
Path = $filename | |
LastWriteTime = $lastWriteTime | |
} | |
} | |
finally{ | |
if($fileHandle){ | |
[void]$kernel32::CloseHandle($fileHandle) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment