Reputation: 41
I am looking for a reliable command-line method of getting SHA256 hashes for files in Windows. My understanding is that the way to do this is via Microsoft's Get-FileHash cmdlet under PowerShell. I have seen several web sites with examples and reviewed Microsoft's own documentation. It appears that the following syntax should work on Windows Server 2012:
Get-FileHash myfile.txt -Algorithm SHA256
The command runs without error, but there is no output. If I send the output to a file, the file is created with no content. I have also seen examples which pipe the output to Format-List; I tried that, but still nothing. I have also tried running the command with invalid arguments, and again nothing.
I am open to using a different program, but due to business requirements, it would need to be a supported download.
Upvotes: 4
Views: 30936
Reputation: 1
I calculated the hash of all files on a drive and exported them to a .csv by using this:
Get-ChildItem C: -Recurse |
Get-FileHash |
Export-Csv -Path C:\Users\yourname\Documents\Output\hashes.csv -NoTypeInformation
Import-Csv -Path C:\Users\yourname\Documents\Output\hashes.csv
Why it works (I think):
Get-ChildItem <--gets everything under your path, in this case C:, and -Recurse gets all the files within folders. You can add limitations if needed.
Get-FileHash <--after you've said get these files, you're saying calculate the hashes
Export-Csv <--says, we're sending your hashes out as comma separated values file, which is crazy helpful, and -Path says put it HERE, -NoTypeInformation just removes the #TYPE row from the top of the .csv file, and versions of PowerShell before 6 need this.
Import-Csv <--says, bring that data into the file at this -Path
Be sure to have the .csv file created in that location before you run the script. The script won't create the container for you. There's no need to clear the data from the .csv file between runs, it clears itself.
I'm not really a programmer, hence the annoyingly lengthy explanation. Hope it helps others. Wouldn't have figured it out without Stack Overflow forums! Thanks everyone!!
Upvotes: -2
Reputation: 107
I'm using PowerShell 4.0 and I just encountered the same problem of null output from Get-FileHash. The cause of my problem is different than the OP but I have found a solution to my problem and I figured I would post my findings for anyone who came to this page trying to solve the problem of null output (or seemingly incorrect output) from Get-FileHash.
The problem only happens (for me) when the path to the target file contains brackets [ ] and those brackets contain either zero characters or 2 or more characters.
EDIT: I now understand WHY this happens. The string is interpreted as Regular Expression (RegEx) so the square brackets [ ] take on their special RegEx meaning. The -LiteralPath tells PowerShell to interpret the string as a simple match (no RegEx).
Consider the following paths which refer to 4 existing text files (hypothetically):
C:\Test\My Text.txt
C:\Test\My [Text].txt
C:\Test\My [Te]xt.txt
C:\Test\My Text[].txt
The following command produces normal output:
Get-FileHash "C:\Test\My Text.txt"
but there will be null output if using the following commands:
Get-FileHash "C:\Test\My [Text].txt"
Get-FileHash "C:\Test\My [Te]xt.txt"
Get-FileHash "C:\Test\My Text[].txt"
This can be solved by using the -LiteralPath switch. For example:
Get-FileHash -LiteralPath "C:\Test\My [Text].txt"
Variables are expanded normally when using the -LiteralPath switch. For example:
(Get-ChildItem C:\Test).FullName | ForEach {
Get-FileHash -LiteralPath $_
}
If there is exactly 1 character between the brackets, the brackets will be ignored when using Get-FileHash.
Consider the following paths which refer to 3 existing text files (hypothetically), each with unique hash values:
C:\Test\My Text.txt
C:\Test\My Tex[t].txt
C:\Test\My[ ]Text.txt
Get-FileHash interprets all three of the following commands in exactly the same way ( the path is interpreted as C:\Test\My Text.txt ) and therefore each command has the exact same output despite each file having it's own unique hash value:
Get-FileHash "C:\Test\My Text.txt"
Get-FileHash "C:\Test\My Tex[t].txt"
Get-FileHash "C:\Test\My[ ]Text.txt"
P.S. I'm a very new programmer, please forgive me for any poor usage of terminology.
Upvotes: 10
Reputation: 1220
Get-FileHash, requires Windows PowerShell 4.0 Based on your comments you are at version 3, which is default on Win 2012 (non R2) Here how to check you PS version
You can update PS on Win 2012 (non R2) to version 4.0 or use Win 2012 R2
If you just run Get-FileHash on a PS version 3 system you should get
PS C:\> Get-FileHash
Get-FileHash : The term 'Get-FileHash' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-FileHash
+ ~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-FileHash:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
On lower PS version you can use this function
Function Get-FileHashTSO([String] $FileName,$HashName = "SHA1")
{
$FileStream = New-Object System.IO.FileStream($FileName,[System.IO.FileMode]::Open)
$StringBuilder = New-Object System.Text.StringBuilder
[System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash($FileStream)|%{[Void]$StringBuilder.Append($_.ToString("x2"))}
$FileStream.Close()
$StringBuilder.ToString()
}
store it as .ps (e.g. Get-FileHashTSO.ps1) file and call it like this
powershell -command "& { . C:\myScripts\Get-FileHashTSO.ps1 ; Get-FileHashTSO "C:\someLocation\someFile.iso" "SHA1" }"
Upvotes: 3