MD5 hash generation (PC)
Overview
As mentioned in this article, creating an
md5 hash (.md5
) of your file can help assure the integrity of your
file after transport through the SFTP layer.
This article provides you with a client side script for generating md5 hash files. This works even with nested subfolders.
PowerShell script for generating hash files
This is the PowerShell script for generating .md5
files:
dir -recurse -name -file | %{
$fileObject = Get-Item $_
$fileName = $fileObect.Name
IF ($fileObject.Extension -ne ".md5") {
$fileHash = (Get-FileHash $_ -Algorithm MD5).Hash.ToLower()
"$fileHash $fileName" | out-file -encoding ascii -filepath "$_.md5" -NoNewline
}
}
To use this script, first cd
to where your files are located on your SFTP client machine.
Then run the script.
It should create an .md5
file for every file in that directory (including nested directories).
Explanation of the bash script
The above script is not easy to reason about, so here's an explanation of how it works.
The following command recursively gets the name of every file in the current directory.
dir -recurse -name -file
This produces the following output:
file1.txt
subfolderA/file2.txt
subfolderA/subfolderB/file3.txt
You can then pipe the output to a for-loop:
dir -recurse -name -file | %{
Write-Output $_
}
%{ }
: This is an alias forForEach-Object
$_
: This is the current object
This produces the same output as before:
file1.txt
subfolderA/file2.txt
subfolderA/subfolderB/file3.txt
Then, you can get properties of the $_
object:
dir -recurse -name -file | %{
$fileObject = Get-Item $_
$fileName = $fileObject.Name
$fileDirectoryName = $fileObject.DirectoryName
Write-Output "Directory: $fileDirectoryName File: $fileName"
}
This produces the output:
Directory: C:\Users\Robert\Documents\temp File: file1.txt
Directory: C:\Users\Robert\Documents\temp\subfolderA File: file2.txt
Directory: C:\Users\Robert\Documents\temp\subfolderA\subfolderB File: file3.txt
To get the file hash, use the Get-FileHash
command:
dir -recurse -name -file | %{
$fileObject = Get-Item $_
$fileName = $fileObject.Name
$fileDirectoryName = $fileObject.DirectoryName
$fileHashObject = Get-FileHash $_ -Algorithm MD5
$fileHash = $fileHashObject.Hash.ToLower()
$fileAlgorithm = $fileHashObject.Algorithm
Write-Output "$fileDirectoryName/$fileName $fileHash"
}
This produces the output:
C:\Users\Robert\Documents\temp\file1.txt 12837cb3a7604fff6919803b631d6495
C:\Users\Robert\Documents\temp\subfolderA\file2.txt 023c61bacb8ca8388480f2b9910d09f2
C:\Users\Robert\Documents\temp\subfolderA\subfolderB\file3.txt d41d8cd98f00b204e9800998ecf8427e
Finally, you want to output this information to an .md5
file.
This is the full version of the script:
dir -recurse -name -file | %{
$fileObject = Get-Item $_
$fileName = $fileObject.Name
$fileDirectoryName = $fileObject.DirectoryName
$fileHashObject = Get-FileHash $_ -Algorithm MD5
$fileHash = $fileHashObject.Hash.ToLower()
$fileAlgorithm = $fileHashObject.Algorithm
"$fileAlgorithm ($fileName) = $fileHash" | out-file -filepath "$fileDirectoryName\$fileName.md5"
}
This creates an .md5
file in the same directory as its original file:
dir -recurse -name -file
file1.txt
file1.txt.md5
subfolderA/file2.txt
subfolderA/file2.txt.md5
subfolderA/subfolderB/file3.txt
subfolderA/subfolderB/file3.txt.md5
And, each .md5
file is formatted so that it can be used by the Linux md5sum -c
command:
cat ./file1.txt.md5
MD5 (file1.txt) = 12837cb3a7604fff6919803b631d6495