I often run chkdsk /f X:(X here stands for actual drive letters), to check and fix filesystem errors, but it doesn't report which files are corrupted.
I use PSCore7.1 on Windows 10 20H2 x64, I want to check which files are corrupted by comparing hash and timestamp of a file against recorded hash and timestamp of that path, if the hash has changed and timestamp hasn't changed, then the file is corrupted.
PowerShell has builtin functions to get hash code, but it isn't SHA-256, I can use
Get-ChildItem -Path $path -Force -File -Recurse
To get files, .Fullname to get full path of files and .LastWriteTime to get timestamp, but here I am talking about whole disks so I want it to be as fast as possible.
But I don't know how to get SHA-256, though it shouldn't be hard.
Then my idea is to create a [PSCustomObject] with three noteproperties: Fullname, LastWriteTime and SHA-256, I can do this, then export it directly to a database file (append), unfortunately currently I only managed to export to txt files, and it would be difficult to query txt files.
Finally if the database doesn't exist, create it and exit, else if it does exist, get content of the database, create a new one in console and look for corrupted files.
I can use [System.IO.File]::Exists() to check if file exists, Convertfrom-String to convert txt to pscustomobject array, though it's buggy, or loop through file by index using for loop, in each iteration get values by regex match then create a PSCustomObject and add to array using +=, though this might be slow.
The final step to find corrupted files would be:
for ($i=0;$i -lt $NewDB.count;$i++) {
$Database | Where-Object{$_.Fullname -eq $NewDB[$i].Fullname -and $_.LastWriteTime -eq $NewDB[$i].LastWriteTime -and $_.SHA256 -ne $NewDB[$i].SHA256}
}
I am not dumb, I am just inexperienced, currently there are there things required by this script which I am unable to do:
1, Get all files of a drive as fast as possible
2, Get SHA-256 of files
3, Export and import data
Please help me complete the script! Any help would be appreciated, I would be very grateful, and the answer may also help many other people, I say thanks in advance.
Update: Now I am looking for ways to export data to csv format, do I just use Out-File *.csv? Will it format data automatically? How do I control the format? And how to convert csv directly into an array of PSCustomObject?
Edit: fixed the missing index in the where line. Re-Edit: completed the for loop and where-object process to make it actually working, just in case someone would doubt my abilities or someone else who sees this and don't know how to do it.
Get-FileHash
should always return SHA256 by default. about the speed ofGet-ChildItem
I wouldn't mind it that much because I wouldn't run this script during working hours anyway, but if you really need it look into.net
methods like[System.IO.Directory]::EnumerateFiles()
. Or use cmd from PowerShell and parse the output in PS. I also saw you can create a VB Object that could also fit your needs. for the SQL Part use SQL Queries likeif exists ... insert into ... update
etc. and run them viaInvoke-SqlCmd