I have been trying to write the md5 hashes for all files in a directory and its subdirectories to a file. Ideally, replicating the output of the Unix command find . -type f -exec md5sum {} +
(i.e. two columns: lowercase hashes and relative file paths [with forward slashes] separated by a space and terminated only by a line feed).
With a lot of help from Mark Wragg, LotPings and others on stackoverflow, the following command appears to compute md5 hashes for all files in a directory and its subdirectories (including those files without file extensions and those with square brackets in the filename).
(Get-FileHash -Algorithm MD5 -LiteralPath (Get-ChildItem -Recurse -File).fullname | ForEach-Object{"{0} {1}" -f $_.Hash.ToLower(),(Resolve-Path -LiteralPath $_.Path -Relative)} | Out-String) -replace '\r(?=\n)' -replace '\\','/' | Set-Content -NoNewline -Encoding ascii $ENV:USERPROFILE\Desktop\hashes.txt
The two uses of -LiteralPath
seems to help with filenames containing square brackets and (Get-ChildItem -Recurse -File).fullname
gets the full path of all nested files, including those without file extensions. The rest is just formatting.
Can any one tell me where I can find more information about .fullname
? I've tried searching for it on Google but without any luck.
I had used Get-ChildItem "*.*" -Recurse
, which gives full file paths but only for files with dots in the filename. Whereas, Get-ChildItem "*" -Recurse
doesn't always give the full path for some reason (and returns both files and folders). Compare:
Get-ChildItem "*.*" -Recurse | foreach-object { "$_" }
Get-ChildItem "*" -Recurse | foreach-object { "$_" }
The order of entries in the hashes file won't be the same as those from the Unix command but compare-object
in PowerShell appears to ignore the order of lines, e.g. (https://serverfault.com/questions/5598/how-do-i-diff-two-text-files-in-windows-powershell)
compare-object (get-content oldHashes.txt) (get-content newHashes.txt)
or
diff (cat oldHashes.txt) (cat newHashes.txt)
-
1\$\begingroup\$ Why MD5 instead of SHA-256? \$\endgroup\$Roland Illig– Roland Illig2019年08月01日 07:06:29 +00:00Commented Aug 1, 2019 at 7:06
1 Answer 1
I rewrote your code from scratch how I would have written it myself. Maybe it can give you some ideas.
$lines = gci -Recurse -File |
Get-FileHash -Algorithm MD5 | % {
$unixPath = $_.Path -replace '\\','/'
$hash = $_.Hash.ToLower()
"$hash $unixPath" }
$lines -join "`n" |
Out-File -Encoding ascii -NoNewline $ENV:USERPROFILE\Desktop\hashes.txt
Notes:
gci
is an alias forGet-ChildItem
.- I used
gci -File
to get files only. %
is an alias forForEach-Object
.- I didn't use it, but here is the help for FileSystemInfo.FullName
cat
is an alias forGet-Content
.
Feel free to ask any questions.