Introducing PowHash
Sep 7, 2016 · 2 minute read · by kdevoUtility PowerShell Scripts
The idea
File Hashing is the correct way to determine data integrity of your downloads and more. Therefore, it’s practical to have built-in OS capabilities to hash files.
The PowerShell provides a nice and easy-to-use way to do that - the Get-FileHash Utility Cmdlet. That’s right: File-Hashing with MD5 and various SHA… variants ready to use in Windows!
Unfortunately, the function doesn’t show the current progress. Well, for small to medium sized files that’s really okay. But: You don’t want to hash a 20 GB file without progress indicator. There also is no “callback parameter” or similar which could be used for progress updates.
Is there really no other way? Well, I figured it out. My initial thought was that the task manager (or e.g. the more feature-rich ProcessExplorer) has access to the OS I/O-statistics like how many bytes are read/written etc. - so why not use this data and calculate an approximation? It’s safe to say that Get-FileHash must read the whole file in any way to calculate the hash.
Further investigations
I searched for functions/cmdlets that could be used to determine how many bytes were already read. After a bit of searching I found Get-Counter:
The Get-Counter cmdlet gets live, real-time performance counter data directly from the performance monitoring instrumentation in Windows.
There is no counter which contains all read bytes, but a useful alternative - “IO Read Bytes/sec”. The basic idea is to read this value every second and sum those values up to give an approximation of the current progress.
After understanding PS runspaces for threading and a bit of scripting, PowHash was born.
A disadvantage is that the “read bytes”-value needs to be cooked first. It takes one second to get a new value.
Therefore, in some cases, the file hashing can take (a maximum of one second) longer than without the progress bar. This could be solved in a future version by also running the Get-Counter invocation in a separate runspace.