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)