无法从get-filehash获取输出

时间:2015-11-06 17:37:05

标签: powershell sha256

我正在寻找一种可靠的命令行方法来获取Windows中文件的SHA256哈希值。我的理解是,这样做的方法是通过PowerShell下的Microsoft的Get-FileHash cmdlet。我看过几个带有示例的网站,并查看了Microsoft自己的文档。似乎以下语法应适用于Windows Server 2012:

Get-FileHash myfile.txt -Algorithm SHA256

该命令运行没有错误,但没有输出。如果我将输出发送到文件,则创建的文件没有内容。我还看到了将输出传递给Format-List的示例;我试过了,但仍然没有。我也尝试使用无效参数运行命令,并且一无所获。

我愿意使用其他程序,但由于业务需求,需要支持下载。

3 个答案:

答案 0 :(得分:2)

我正在使用PowerShell 4.0,我刚刚遇到了Get-FileHash的null输出问题。我的问题的原因与OP有所不同,但我找到了解决我的问题的方法,我想我会发现我的发现给那些来到这个页面的人试图解决Get输出的空输出(或看似不正确的输出)的问题-FileHash。

当目标文件的路径包含方括号[]并且这些方括号包含零个字符或两个或更多字符时,问题才会发生(对我而言)。

编辑:我现在明白为什么会这样。该字符串被解释为正则表达式(RegEx),因此方括号[]采用其特殊的RegEx含义。 -LiteralPath告诉PowerShell将字符串解释为简单匹配(无RegEx)。

考虑以下路径引用4个现有文本文件(假设):

C:\Test\My Text.txt
C:\Test\My [Text].txt
C:\Test\My [Te]xt.txt
C:\Test\My Text[].txt

以下命令产生正常输出:

Get-FileHash "C:\Test\My Text.txt"

但是如果使用以下命令,则会有空输出:

Get-FileHash "C:\Test\My [Text].txt"
Get-FileHash "C:\Test\My [Te]xt.txt"
Get-FileHash "C:\Test\My Text[].txt"

这可以通过使用-LiteralPath开关来解决。例如:

Get-FileHash -LiteralPath "C:\Test\My [Text].txt"

使用-LiteralPath开关时,变量会正常扩展。例如:

(Get-ChildItem C:\Test).FullName | ForEach {
Get-FileHash -LiteralPath $_
}

如果括号中只有1个字符,则在使用Get-FileHash时将忽略括号。

考虑以下路径引用3个现有文本文件(假设),每个文件都有唯一的哈希值:

C:\Test\My Text.txt
C:\Test\My Tex[t].txt
C:\Test\My[ ]Text.txt

Get-FileHash以完全相同的方式解释以下所有三个命令(路径被解释为C:\ Test \ My Text.txt),因此每个命令都具有完全相同的输出,尽管每个文件都有自己唯一的哈希值:

Get-FileHash "C:\Test\My Text.txt"
Get-FileHash "C:\Test\My Tex[t].txt"
Get-FileHash "C:\Test\My[ ]Text.txt"

P.S。我是一个非常新的程序员,请原谅我使用不当的术语。

答案 1 :(得分:1)

Get-FileHash,需要 Windows PowerShell 4.0 根据您的评论,您的版本为3,这是Win 2012(非R2)Here how to check you PS version

的默认值

您可以将Win 2012(非R2)上的PS更新为4.0版或使用Win 2012 R2

如果你只是在PS版本3系统上运行 Get-FileHash ,你应该得到

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

在较低的PS版本上,您可以使用此功能

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() 
}

将其存储为.ps(例如Get-FileHashTSO.ps1)文件并将其称为

powershell -command "& { . C:\myScripts\Get-FileHashTSO.ps1 ; Get-FileHashTSO "C:\someLocation\someFile.iso" "SHA1" }"

答案 2 :(得分:0)

我使用以下方法计算了驱动器上所有文件的哈希值,并将它们导出到.csv:

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

为什么有效(我认为):

Get-ChildItem <-获取路径下的所有内容,在本例中为C :,而-Recurse获取文件夹中的所有文件。您可以根据需要添加限制。

Get-FileHash <-说完获取这些文件之后,就是说要计算散列值

Export-Csv <-表示,我们将哈希值作为逗号分隔的值文件发送出去,这非常有用,并且-Path表示放在这里,-NoTypeInformation只是从顶部删除了#TYPE行.csv文件以及6之前的PowerShell版本。

Import-Csv <-例如,将数据通过此-Path导入文件中

在运行脚本之前,请确保在该位置创建了.csv文件。该脚本不会为您创建容器。无需在运行之间清除.csv文件中的数据,它会自行清除。

我不是真正的程序员,因此冗长的解释很烦人。希望它能帮助别人。没有Stack Overflow论坛就不会弄清楚!谢谢大家!