PowerShell 的 Get-FileHash 命令查询一个文件的所有上述哈希值(假设是 SHA256, MD5, SHA1, SHA384, 和 SHA512),你需要分别对每个算法运行该命令
Get‑FileHash 拆解 解构 底层原理 依赖文件 依赖关系 逻辑链路 配套链
定位:Get‑FileHash是 PowerShell 内置 Cmdlet,用于计算文件哈希(MD5、SHA1、SHA256、SHA384、SHA512);PowerShell 5.1 / PowerShell 7+ 均原生自带,不需要额外安装模块。
PowerShell: Get‑FileHash [-Path] <string> [-Algorithm]
↓
Microsoft.PowerShell.Utility.dll (Cmdlet托管实现)
↓
.NET System.Security.Cryptography 哈希抽象类
↓
Windows CNG(Cryptography Next Generation) / CryptoAPI
↓
Win32文件API ReadFile 读取文件字节流
↓
文件磁盘数据送入哈希算法 → 输出哈希摘要 → 封装为FileHash对象输出
一、底层原理
1、Cmdlet 本体
Get‑FileHash 属于 Microsoft.PowerShell.Utility 模块,编译在 Microsoft.PowerShell.Utility.dll。
FileHash 对象。SHA256(默认算法)、SHA1、SHA384、SHA512、MD5
MD5/SHA1 仅兼容用途,不建议安全校验场景使用。
2、.NET 密码学层
System.Security.Cryptography.HashAlgorithm 抽象工厂:HashAlgorithm.Create(algorithmName);
- Windows 平台:底层调用 CNG(下一代密码学),
bcrypt.dll,硬件支持时可使用 CPU 指令加速哈希计算; - 不是 PowerShell 自己实现哈希算法,只是做文件 IO + 调用系统密码学库。
3、文件读取逻辑(重点)
- 以只读模式打开文件流
FileStream; - 分块缓冲区读取(默认缓冲区大小),不会一次性把整个文件全部加载进内存;
大文件(几十 GB)也可以正常计算哈希,不会爆内存;逐块送入哈希更新TransformBlock()。
- 全部流读完,调用
TransformFinalBlock()获取最终哈希字节摘要。 - 将字节摘要转为十六进制大写字符串。
- 封装为
FileHashPSObject 输出,包含:Path、Algorithm、Hash属性。
⚠️重要特性:Get‑FileHash计算的是文件内容哈希;文件名称、修改时间、元数据不参与哈希计算;只有文件字节内容改变,Hash 才变化。
4、路径支持
字符串哈希需要手动实例化.NET HashAlgorithm。
二、依赖文件清单
| 文件 | 作用 |
|---|---|
Microsoft.PowerShell.Utility.dll |
Get‑FileHash Cmdlet 托管实现 |
System.Security.Cryptography.dll |
.NET 哈希算法抽象层 |
bcrypt.dll |
Windows CNG 密码学原生库,实际哈希运算 |
kernel32.dll |
Win32 文件 API:CreateFile、ReadFile,读取磁盘文件 |
运行环境:
- PowerShell5.1:依赖 .NET Framework;
- PowerShell7+:依赖 .NET Core;跨平台 Windows/Linux/macOS 均可用。
三、依赖关系梳理
-
权限依赖需要目标文件读取权限;没有读权限直接抛出文件访问异常。不需要管理员权限,普通用户可读文件即可计算哈希。
-
文件系统依赖
- 文件被其他程序独占锁定:Get‑FileHash 打开失败,报文件正在使用;
- 网络 UNC 路径:依赖 SMB 连通性,受网络抖动影响。
-
算法可用性依赖MD5、SHA1、SHA2 系列依赖系统 CNG 密码提供程序;极简 / 安全加固裁剪系统下极少数密码算法被策略禁用,会抛出算法不支持。
-
内存模型优势分块流式计算,文件大小不占用对等内存;无论几 GB 文件,缓冲区固定大小。
-
输出对象依赖输出是
FileHash对象;如果直接输出到文本,PowerShell 会做格式化;导出原始哈希值建议访问.Hash属性。
四、完整逻辑链路
链路:Get‑FileHash C:\test.iso -Algorithm SHA256
- PowerShell 解析命令,定位内置 Cmdlet
Get‑FileHash; - 参数绑定:Path 赋值文件路径,Algorithm 选择 SHA256;
- Cmdlet 内部调用.NET
FileStream只读打开目标文件; - 根据 Algorithm 名称,工厂创建对应的
HashAlgorithm实例(底层绑定 bcrypt CNG); - 循环分块读取磁盘文件字节流;每一块调用
HashAlgorithm.TransformBlock()更新哈希状态; - 文件读取完毕,执行
TransformFinalBlock(),得到最终哈希字节数组; - 将字节数组转为大写十六进制字符串;
- 构造
FileHash对象,填充Path、Algorithm、Hash;输出到 PowerShell 管道。 - 自动释放 FileStream 与 HashAlgorithm 资源。
关键:哈希计算是流式迭代更新,不是全部读完再计算。
五、配套链:实操示例
# 默认SHA256
Get‑FileHash C:\test.iso
# 指定MD5
Get‑FileHash C:\test.iso ‑Algorithm MD5
# 只输出哈希字符串
(Get‑FileHash C:\test.iso).Hash
# 批量计算目录下全部文件哈希
Get‑ChildItem C:\test\* ‑File | Get‑FileHash
# 输出到CSV
Get‑ChildItem C:\test\* ‑File | Get‑FileHash | Export‑Csv hashlist.csv ‑NoTypeInformation
补充:如果需要对字符串计算哈希(Get‑FileHash 做不到),直接调用.NET 哈希类:
$enc = [System.Text.Encoding]::UTF8
$bytes = $enc.GetBytes("teststring")
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$hashBytes = $sha256.ComputeHash($bytes)
[BitConverter]::ToString($hashBytes).Replace("-","")
六、故障排查清单
- Get‑FileHash : 无法访问文件
文件不存在 / 路径错误 / 当前用户没有文件读权限 / 文件被独占锁定。
- 算法名称无效
只支持:SHA256、SHA1、SHA384、SHA512、MD5;拼写错误会报错。
- 大文件执行慢,但内存占用很低
属于正常现象:磁盘 IO 瓶颈,流式计算不会吃内存。
- 同一个文件,两台机器哈希不一样
确认文件字节是否完全一致;元数据、时间戳不影响哈希;只要 Hash 不同,文件字节一定存在差异。
- UNC 网络文件哈希计算慢
全部文件字节需要通过网络 SMB 读取,受带宽影响。
七、关键认知误区澄清
PowerShell 是一种跨平台的任务自动化解决方案,包含一个命令行外壳、脚本语言和配置管理框架。PowerShell 提供了用于计算文件哈希值的内置命令 Get-FileHash。Get-FileHash 命令可以用来计算文件的哈希值,支持多种哈希算法。 ,Get-FileHash 支持以下几种哈希算法:
- SHA256:默认算法,提供了较好的安全性。
- MD5:较早的算法,现在不推荐使用,因为其安全性较低。
- SHA1:比MD5新,但是现在也被认为是不够安全的。
- SHA384:比SHA256更长的哈希值,提供更高的安全性。
- SHA512:比SHA384还要长的哈希值,提供最高的安全性。
如果在将 Get-FileHash 的输出重定向到文本文件时遇到哈希值显示不完整的问题,这通常是因为输出格式化的原因。为了确保哈希值在输出文件中完整显示,最好直接提取哈希值属性进行输出。以下是如何做到这一点的步骤:
1. 直接输出哈希值到文件
你可以只提取哈希值本身(通过访问 .Hash 属性),然后将这个值输出到文件,这样可以确保哈希值不会被截断。
(Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512).Hash | Out-File -FilePath C:\output.txt
这条命令首先计算指定文件的 SHA512 哈希值,然后直接从结果对象中提取 Hash 属性的值(即哈希值字符串),最后将这个字符串写入 C:\output.txt 文件中。
2. 使用自定义格式化输出到文件
如果你还想在输出文件中包含算法名称和路径等信息,但又希望哈希值完整无缩略,可以使用自定义的 PowerShell 脚本片段来格式化输出内容。
$fileHash = Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512
$outputString = "Algorithm: $($fileHash.Algorithm)`r`nHash: $($fileHash.Hash)`r`nPath: $($fileHash.Path)"
$outputString | Out-File -FilePath C:\output.txt
这段脚本首先计算文件的哈希值,并将结果存储在 $fileHash 变量中。然后,它构造一个包含算法、哈希值和路径的字符串($outputString),其中哈希值是完整的,没有被截断。最后,这个字符串被写入到指定的文件中。
这样,无论哈希值有多长,都可以确保在输出文件中完整地展示出来,同时还能包含一些额外的有用信息。
在 PowerShell 中,当你使用 Get-FileHash 命令获取文件的哈希值时,如果哈希值很长(如 SHA512),输出可能会被截断以适应控制台窗口的宽度。为了显示完整的哈希值,你可以尝试以下几种方法:
1. 增加控制台窗口的宽度
这是最简单的解决方案之一,尽管它可能不总是可行或方便。你可以尝试手动调整 PowerShell 窗口的宽度,使其足够宽,以便能够显示完整的哈希值。
2. 使用 Format-Table 命令的 -Wrap 参数
Format-Table 是 PowerShell 中用于格式化输出的一个命令,它有一个 -Wrap 参数,可以用来包装长文本,以便在下一行继续显示,而不是截断它。
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Format-Table -AutoSize -Wrap
3. 使用 Format-Table 命令的 -AutoSize 参数
虽然 -AutoSize 参数主要用于自动调整列的宽度以适应内容,但它有时也可以帮助更好地显示长文本。
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Format-Table -AutoSize
4. 直接输出哈希值属性
如果你只对哈希值本身感兴趣,可以直接选择 .Hash 属性,这样就会输出完整的哈希值,而不包含其他信息。
(Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512).Hash
5. 输出到文件
另一个选项是将输出重定向到一个文本文件中,这样你就可以用文本编辑器打开它并查看完整的哈希值。
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Out-File -FilePath C:\path\to\output.txt
请将 C:\path\to\output.txt 替换为你想要保存输出文件的实际路径。然后,你可以使用任何文本编辑器打开这个文件来查看完整的哈希值。
以上方法中的任何一个都可以帮助你查看到完整的哈希值,具体使用哪一个取决于你的个人偏好和具体情况。
你可以通过指定 -Algorithm 参数来选择这些算法中的任何一个。例如,如果你想为某个文件计算SHA512哈希值,可以使用如下命令:
Get-FileHash -Path "C:\path\to\your\file.txt" -Algorithm SHA512
这会返回该文件的SHA512哈希值。
请注意,随着时间的推移,可能会有更多的哈希算法被添加到PowerShell中,或者一些算法可能因安全考虑而不再推荐使用。因此,建议查看最新的PowerShell文档或使用 Get-Help Get-FileHash 命令来获取最新信息。
要使用 PowerShell 的 Get-FileHash 命令查询一个文件的所有上述哈希值(假设是 SHA256, MD5, SHA1, SHA384, 和 SHA512),你需要分别对每个算法运行该命令。PowerShell 不提供直接查询所有哈希值的单一命令,但你可以通过编写一个简短的脚本来实现这一功能。
以下是一个示例脚本,它将为指定路径的文件计算所有提及的哈希值:
# 指定文件路径
$filePath = "C:\path\to\your\file.txt"
# 定义支持的哈希算法列表
$hashAlgorithms = @("SHA256", "MD5", "SHA1", "SHA384", "SHA512")
# 遍历算法列表,为每种算法计算哈希值
foreach ($algorithm in $hashAlgorithms) {
$hash = Get-FileHash -Path $filePath -Algorithm $algorithm
Write-Output "$algorithm hash of `"$filePath`": $($hash.Hash)"
}
将上面的脚本保存到一个 .ps1 文件中或直接在 PowerShell 控制台中运行它。确保替换 $filePath 变量的值为你想要计算哈希值的文件的实际路径。这个脚本会遍历所有指定的哈希算法,为每一个算法输出对应的哈希值。
PowerShell 的 Get-FileHash 命令主要支持的哈希算法包括了你提到的 SHA256, MD5, SHA1, SHA384, 和 SHA512。这些算法是最常用且广泛支持的。
除了这些常见的算法,根据不同版本的 PowerShell 和 Windows 环境,可能还有其他哈希算法可用,但它们并不是 Get-FileHash 命令的标准选项。Get-FileHash 命令的设计初衷是提供一种简单方式来计算文件的哈希值,因此它只包含了一些最广泛使用的算法。
如果需要计算其他类型的哈希值,你可能需要依赖其他工具或自定义脚本来实现。例如,可以使用 .NET 类库中的加密功能来计算其他类型的哈希值。下面是一个使用 .NET 类库计算 RIPEMD-160 哈希值的示例:
# 加载目标类
$ripemd160 = [System.Security.Cryptography.RIPEMD160Managed]::new()
# 计算哈希值
function Get-RipeMD160Hash($filePath) {
$fileStream = [System.IO.File]::OpenRead($filePath)
$hashValue = $ripemd160.ComputeHash($fileStream)
$fileStream.Close()
return [BitConverter]::ToString($hashValue) -replace '-', ''
}
# 使用函数
$filePath = "C:\path\to\your\file.txt"
$hash = Get-RipeMD160Hash $filePath
Write-Output "RIPEMD-160 hash of `"$filePath`": $hash"
请注意,RIPEMD-160 只是作为示例,而且在某些环境中可能不直接支持。此外,对于特定的哈希算法,你可能需要安装额外的软件或库。
在密码学和信息安全领域,除了上文提及的 SHA256, MD5, SHA1, SHA384, 和 SHA512 等哈希算法外,还存在许多其他的哈希函数。它们各自有不同的设计目的、安全性水平和应用场景。以下是一些其他的哈希算法,虽然这些可能不直接通过 PowerShell 的 Get-FileHash 命令支持,但它们在某些特定的应用中很重要:
-
RIPEMD-160: 一种较旧的哈希函数,设计用于替代 MD4、MD5 和 RIPEMD。RIPEMD-160 输出为160位。

浙公网安备 33010602011771号