Unable to get output from get-filehash

前端 未结 3 1372
[愿得一人]
[愿得一人] 2020-12-21 10:43

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

相关标签:
3条回答
  • 2020-12-21 11:20

    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.

    0 讨论(0)
  • 2020-12-21 11:36

    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" }"
    
    0 讨论(0)
  • 2020-12-21 11:37

    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!!

    0 讨论(0)
提交回复
热议问题