Here is the script use at your own risk:
# Modify the directory that you are looking at and the timestamps $currentDirectory = "c:\windows" $files = Get-ChildItem $currentDirectory # Change the below line to look like the below if you want to recursively look at the files in a directory #$files = Get-ChildItem $currentDirectory -Recurse $startDate = Get-Date 2020-03-01 $endDate = Get-Date 2020-06-30 # Only outputs results where a creation time, last access time, and last write time are within the timeframe listed above # Added the function to look at the MFT File Record for the file being examined. If that time is within the timeframe it # is also captured... # # Looking at the MFT File Record will indicate time stomping... Function Color-Text { param ( $inDate) If (($inDate -ge $startDate) -and ($inDate -le $endDate)) { Write-Host "$($inDate) " -ForegroundColor Yellow -NoNewline } Else { Write-Host "$($inDate) " -NoNewline } } Function Get-ChangeTime { # This function is from https://gallery.technet.microsoft.com/scriptcenter/Get-MFT-Timestamp-of-a-file-9227f399 # Modified to work in this context. param ( $inFile ) $FileStream = [System.IO.File]::Open($inFile, 'Open', 'Read', 'ReadWrite') #$FileStream #[void][ntdll] #region Module Builder $Domain = [AppDomain]::CurrentDomain $DynAssembly = New-Object System.Reflection.AssemblyName('TestAssembly') $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) # Only run in memory $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('TimeStampModule', $False) #endregion Module Builder #region ENUMs $EnumBuilder = $ModuleBuilder.DefineEnum('FileInformationClass', 'Public', [UInt32]) # Define values of the enum [void]$EnumBuilder.DefineLiteral('FileDirectoryInformation', [UInt32] 1) [void]$EnumBuilder.DefineLiteral('FileBasicInformation', [UInt32] 4) [void]$EnumBuilder.DefineLiteral('FileModeInformation', [UInt32] 16) [void]$EnumBuilder.DefineLiteral('FileHardLinkInformation', [UInt32] 46) #Create ENUM Type [void]$EnumBuilder.CreateType() #endregion ENUMs #region FileBasicInformation #Define STRUCT $Attributes = 'AutoLayout, AnsiClass, Class, ExplicitLayout, Sealed, BeforeFieldInit,public' $TypeBuilder = $ModuleBuilder.DefineType('FileBasicInformation', $Attributes, [System.ValueType], 8, 0x28) $CreateTimeField = $TypeBuilder.DefineField('CreationTime', [UInt64], 'Public') $CreateTimeField.SetOffset(0) $LastAccessTimeField = $TypeBuilder.DefineField('LastAccessTime', [UInt64], 'Public') $LastAccessTimeField.SetOffset(8) $LastWriteTimeField = $TypeBuilder.DefineField('LastWriteTime', [UInt64], 'Public') $LastWriteTimeField.SetOffset(16) $ChangeTimeField = $TypeBuilder.DefineField('ChangeTime', [UInt64], 'Public') $ChangeTimeField.SetOffset(24) $FileAttributesField = $TypeBuilder.DefineField('FileAttributes', [UInt64], 'Public') $FileAttributesField.SetOffset(32) #Create STRUCT Type [void]$TypeBuilder.CreateType() #endregion FileBasicInformation #region IOStatusBlock #Define STRUCT $Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' $TypeBuilder = $ModuleBuilder.DefineType('IOStatusBlock', $Attributes, [System.ValueType], 1, 0x10) [void]$TypeBuilder.DefineField('status', [UInt64], 'Public') [void]$TypeBuilder.DefineField('information', [UInt64], 'Public') #Create STRUCT Type [void]$TypeBuilder.CreateType() #endregion IOStatusBlock #region DllImport $TypeBuilder = $ModuleBuilder.DefineType('ntdll', 'Public, Class') #region NtQueryInformationFile Method $PInvokeMethod = $TypeBuilder.DefineMethod( 'NtQueryInformationFile', #Method Name [Reflection.MethodAttributes] 'PrivateScope, Public, Static, HideBySig, PinvokeImpl', #Method Attributes [IntPtr], #Method Return Type [Type[]] @([Microsoft.Win32.SafeHandles.SafeFileHandle], [IOStatusBlock], [IntPtr] ,[UInt16], [FileInformationClass]) #Method Parameters ) $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) $FieldArray = [Reflection.FieldInfo[]] @( [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'), [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') ) $FieldValueArray = [Object[]] @( 'NtQueryInformationFile', #CASE SENSITIVE!! $True ) $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder( $DllImportConstructor, @('ntdll.dll'), $FieldArray, $FieldValueArray ) $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) #endregion NtQueryInformationFile Method [void]$TypeBuilder.CreateType() #endregion DllImport $fbi = New-Object "FileBasicInformation" $iosb = New-Object "IOStatusBlock" $p_fbi = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Runtime.InteropServices.Marshal]::SizeOf($fbi)) # Pull file timestamps from file #[DllImport("ntdll.dll", SetLastError=$true)] $iprc = [ntdll]::NtQueryInformationFile($FileStream.SafeFileHandle, $iosb, $p_fbi, [System.Runtime.InteropServices.Marshal]::SizeOf($fbi), [FileInformationClass]::FileBasicInformation ) # Check to make sure no issues occurred $IsOK = (($iprc -eq [intptr]::Zero) -AND ($iosb.status -eq 0)) If ($IsOK) { # Pull data from unmanaged memory block into a usable object # The below line in the original document does notwork. Add [System.Type] in the front and it works... # https://poshsecurity.com/blog/2014/2/3/powershell-error-the-specified-structure-must-be-blittable-o.html $fbi = [System.Runtime.InteropServices.Marshal]::PtrToStructure($p_fbi, [System.Type][FileBasicInformation]) #$Object = [pscustomobject]@{ # FullName = $FileStream.Name # CreationTime = [datetime]::FromFileTime($fbi.CreationTime) # LastAccessTime = [datetime]::FromFileTime($fbi.LastAccessTime) # LastWriteTime = [datetime]::FromFileTime($fbi.LastWriteTime) # ChangeTime = [datetime]::FromFileTime($fbi.ChangeTime) #} #$Object.PSTypeNames.Insert(0,'System.Io.FileTimeStamp') return [datetime]::FromFileTime($fbi.ChangeTime) } Else { return "$($Item): $(New-Object ComponentModel.Win32Exception)" } #region Perform Cleanup $FileStream.Close() # Deallocate memory If ($p_fbi -ne [intptr]::Zero) { [System.Runtime.InteropServices.Marshal]::FreeHGlobal($p_fbi) } } ForEach ($file in $files) { $creationTime = $file.CreationTime $lastAccessTime = $file.LastAccessTime $lastWriteTime = $file.LastWriteTime Try { If ($file.Attributes -notmatch 'Directory') { $changeTime = Get-ChangeTime -inFile $file.FullName } Else { # Arbitrary change time if one is not found by the function... $changeTime = (Get-Date).AddYears(-20) } } Catch { # Arbitrary change time if one is not found by the function... $changeTime = (Get-Date).AddYears(-20) } # Only output what matches the criteria above # If the MFT time of creation matches the timeframe it is output If ((($creationTime -ge $startDate) -and ($creationTime -le $endDate)) -or (($lastAccessTime -ge $startDate) -and ($lastAccessTime -le $endDate)) -or (($lastWriteTime -ge $startDate) -and ($lastWriteTime -le $endDate)) -or (($changeTime -ge $startDate) -and ($changeTime -le $endDate))) { Write-Host "-- File Information --" Write-Host "Name: " -NoNewLine -ForegroundColor Green Write-Host "$($file.FullName)" Write-Host "Attributes: " -NoNewline -ForegroundColor Green Write-Host "$($file.Attributes)" Write-Host "Length: " -NoNewline -ForegroundColor Green Write-Host "$($file.Length)" If ($file.Attributes -notmatch 'Directory') { $changeTime = Get-ChangeTime -inFile $file.FullName Write-Host "MFT Change Time: " -NoNewline -ForegroundColor Green Write-Host (Color-Text -inDate $changeTime) } Write-Host "Create: " -NoNewline -ForegroundColor Green Write-Host (Color-Text -inDate $creationTime) -NoNewline Write-Host "Last Access Time: " -NoNewline -ForegroundColor Green Write-Host (Color-Text -inDate $lastAccessTime) -NoNewline Write-Host "Last Write Time: " -NoNewline -ForegroundColor Green Write-Host (Color-Text -inDate $lastWriteTime) If ($file.Attributes -notmatch 'Directory') { $md5 = (Get-FileHash -LiteralPath $file.FullName -Algorithm MD5 -ErrorAction SilentlyContinue).Hash $sha1 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA1 -ErrorAction SilentlyContinue).Hash $sha256 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash Write-Host "-- Hashes --" Write-Host "MD5: " -NoNewline -ForegroundColor Green Write-Host $md5 Write-Host "SHA1: " -NoNewline -ForegroundColor Green Write-Host $sha1 Write-Host "SHA256: " -NoNewline -ForegroundColor Green Write-Host $sha256 } Write-Host "`r`n`r`n" } }