Anything as Code: Check Uploaded File Hash. Introduction. Function Check-UploadedFileHash. Brief Summary.

Introduction


Hello to all readers of the SDDC and Architecture, Solution, Implementation and Operations as Code blog.

Today, I will continue to talk about such a conceptual approach as Operations as Code as a component of the Anything as Code strategy.

In the previous post, Anything as code: Upload File to ESXi Datasore, I talked about the function that performs the task of uploading a file to the ESXi datasore. Functions are passed to the input the necessary parameters in the form of a variable, changing which you can also use a code reuse strategy.

Today we will take the next step and consider the following situation: The file is uploaded to the datastore of the hypervisor, but during operation we observe some errors. So I want to be sure that the file was uploaded correctly. To do this, you need to calculate the hash of the file and compare it with the correct one.

Moreover, for the efficiency of the work process, this action should be performed on the hypervisor side with the appropriate built-in tools.

So, for your attention, the PowerShell function Check-UploadedFileHash.

Check-UploadedFileHash


So let’s look at the code for the Check-UploadedFileHash function:

Function Check-UploadedFileHash {

<#
.SYNOPSIS
    Check file Hash Uploaded to ESXi datastore.  

.DESCRIPTION
    Check file Hash Uploaded to ESXi datastore. 

.PARAMETER Target
    Name or IP Address of the VMware ESXi.

.PARAMETER File
    Name of file.

.PARAMETER Datastore
    Name of ESXi Datastore.

.PARAMETER Folder
    Name of ESXi Datastore Folder.

.PARAMETER Algorithm
    Algorithm for calculate Hash.

.PARAMETER Hash
    Reference File Hash.

.NOTES
    Version:        0.1
    Author:         Andrii Romanenko
    Website:        blogs.airra.net
    Creation Date:  10.08.2023
    Purpose/Change: Initial script development

    Version:        0.2
    Author:         Andrii Romanenko
    Change Date:    02.01.2024
    Purpose/Change: Purpose/Change: Reorganize Function. Add Workflow Time Measuring External Function: Get-CalculateWorkingTime.
                                                         Add ValidateSet $Algorithm in Input Parameters
                                                         Add Case Algorithm Command and Output
    Version:        0.3
    Author:         Andrii Romanenko
    Change Date:    08.01.2024
    Purpose/Change: Purpose/Change: Reorganize Function. Rename function name to Check-UploadedFileHash and some variables.

.EXAMPLE

    $Parameters = @{
        Target    = $ESXiHost
        Datastore = $ISODatastore
        Folder    = "ISO\"
        File      = "en_windows_8_1_x64_dvd_2707217.iso"
        Algorithm = "SHA256"
        Hash      = "23DCCB255FA73CE6E93B12FEFEEFB7204C1681B9A343B51126D3D79F3A34BCD3"
    }
    Check-UploadedFileHash @Parameters

    $Parameters = @{
        Target    = $ESXiHost
        Datastore = $ISODatastore
        Folder    = "ISO\"
        File      = "en_windows_8_1_x64_dvd_2707217.iso"
        Algorithm = "MD5"
        Hash      = "f104b78019e86e74b149ae5e510f7be9"
    }
    Check-UploadedFileHash @Parameters

    $Parameters = @{
        Target    = $ESXiHost
        Datastore = $ISODatastore
        Folder    = "ISO\"
        File      = "en_windows_8_1_x64_dvd_2707217.iso"
        Algorithm = "SHA1"
        Hash      = "bc2f7ff5c91c9f0f8676e39e703085c65072139b"
    }
    Check-UploadedFileHash @Parameters

    $Parameters = @{
        Target    = $ESXiHost
        Datastore = $ISODatastore
        Folder    = "ISO\"
        File      = "en_windows_8_1_x64_dvd_2707217.iso"
        Algorithm = "SHA512"
        Hash      = "25446f98ea6cf35e95ecb0cb3ff9584e67c252d78ca0ac98f08e97d9aa62ddf537ea9c55f6e730abfa09b5759c16d4d2a6ad64ff356a62db914495f203b92807"
    }
    Check-UploadedFileHash @Parameters
#>

param ( 
    [Parameter(Mandatory)][string]$Target,
    [Parameter(Mandatory)][string]$File,
    [Parameter(Mandatory)][string]$Datastore,
    [Parameter(Mandatory)][string]$Folder,
    [Parameter(Mandatory)][ValidateSet('SHA1','SHA256','SHA512','MD5')][string]$Algorithm,
    [Parameter(Mandatory)][string]$Hash
)

# Get start time of the Check File Hash operation
$StartTime = Get-Date           
$Message = "Begin Check Hash: "  + $Image + " on Datastore: " + $Datastore + " on Target:" + $Target + "."
Write-Host -ForegroundColor Green $Message

# Check if SSH service on ESXI is running
$SSHServiceStatus = Get-VMHost | Get-VMHostService | Where { $_.Key -eq "TSM-SSH" }
If ($SSHServiceStatus.Running -eq "True")
{
$Message = "SSH Service is running. Nothing To Do."
Write-Host -ForegroundColor Green $Message
}
Else
{
$Message = "SSH Service is NOT running. Starting Service"
Write-Host -ForegroundColor Red $Message
Get-VMHost | Get-VMHostService | Where { $_.Key -eq "TSM-SSH" } | Start-VMHostService
}

# Open SSH session
$Message = "Open SSH Session to host: " + $Target + "."
Write-Host -ForegroundColor Green $Message
$SSHSession = New-SSHSession -ComputerName $Target –AcceptKey -Credential $Script:ESXISessionCredentials

# Check File Hash
$Message = "Begin Calculate Hash of file: " + $File + " on Datastore: " + $Datastore + "." 
Write-Host -ForegroundColor Green $Message

# Get Datasore ID
$DataStoreID = (Get-VMHost | Get-Datastore -Name $Datastore)
$DataStoreID = $DataStoreID.ID.Substring(10)

# Case AlgoritmCommand
Switch ($Algorithm) {
    "SHA1" { $AlgorithmCommand = "sha1sum"}
    "SHA256" { $AlgorithmCommand = "sha256sum"}
    "SHA512" { $AlgorithmCommand = "sha512sum"}
    "MD5" { $AlgorithmCommand = "md5sum"}
}

$SSHCommand = $AlgorithmCommand
$SSHCommand += ' /vmfs/volumes/'
$SSHCommand += $DataStoreID
$SSHCommand += '/'
$SSHCommand += $Folder.Replace("\", "/")
$SSHCommand += $File

$Result = Invoke-SSHCommand -SSHSession $SSHSession -Command $SSHCommand
#Write-Host $Result.Output

# Case Algoritm Output
Switch ($Algorithm) {
    "SHA1" { $HashResult = $Result.Output.Substring(0,40)}
    "SHA256" { $HashResult = $Result.Output.Substring(0,64)}
    "SHA512" { $HashResult = $Result.Output.Substring(0,128)}
    "MD5" { $HashResult = $Result.Output.Substring(0,32)}
}

$Message = "End Calculate Hash of file: " + $File + " on Datastore: " + $Datastore + "." 
Write-Host -ForegroundColor Green $Message

# Check Result
$Message = "Begin Check Hash of file: " + $File + "." 
Write-Host -ForegroundColor Green $Message

$Result=$HashResult.ToUpper().Equals($Hash.ToUpper())

If ($Result -eq "True")
{
$Message = "Hash Valid"
Write-Host -ForegroundColor Green $Message
}
Else
{
$Message = "Hash Not Valid"
Write-Host -ForegroundColor Red $Message
}
$Message = "End Check Hash of file: " + $File + "." 
Write-Host -ForegroundColor Green $Message

# Remove SSH Session
$Message = "Close SSH Session to host: " + $Target + "."
Write-Host -ForegroundColor Green $Message
Remove-SSHSession $SSHSession | Out-Null

# Get end time of the operation
$EndTime = Get-Date

# Calculate Elapsed Time of the operation
Get-CalculateWorkingTime -StartTime $StartTime -EndTime $EndTime
}

The function accepts the following mandatory parameters as input in the form of the @Parameters variable:

  • Target – Name or IP Address of the VMware ESXi;
  • File – Checked File Name;
  • Datastore – Name of ESXi Datastore;
  • Folder – Name of ESXi Datastore Folder;
  • Algorithm – Algorithm for calculate Hash;
  • Hash – Reference File Hash.

At the beginning of work, the start time is fixed in the form of the $StartTime variable.

The function will use the Posh-SSH Powershell module for its work to connect to the ESXi hypervisor and execute commands in the SSH environment. Therefore, the next step is to check whether this service is running on the hypervisor side, and if not, to start it.

This action is performed by standard PowerCLI cmdlets Get-VMHost, Get-VMHostService, Start-VMHostService.

Next, open an SSH session to the ESXi host New-SSHSession. This cmdlet is already from the Posh-SSH module.

For the algorithm to calculate the hash of the file, you will need to specify the path to the location of the file on the ESXi datastore. To do this, you should get a datastore identifier:

$DataStoreID = (Get-VMHost | Get-Datastore -Name $Datastore)

$DataStoreID = $DataStoreID.ID.Substring(10)

Different algorithms can be used to calculate the hash of a file. Their list is limited to the input variable $Algorithm and contains the following values: ‘SHA1′,’SHA256′,’SHA512′,’MD5’.

Depending on the value of the variable, the appropriate command will be used: sha1sum, sha256sum, sha512sum, md5sum. The Switch ($Algorithm) Powershell structure helps in this.

The $SSHCommand variable forms a command that should be sent to the SSH session. The result of the SSH Command goes into the $Result variable.

Depending on the hash calculation algorithm, the variable will contain a text fragment of different lengths. Therefore, depending on the $Algorithm variable, the required number of characters will be allocated. What will correspond to the calculated hash: sha1sumSubstring(0.40), sha256sumSubstring(0.64), sha512sumSubstring(0,128), md5sumSubstring(0,32).

Finally, the calculated hash is compared with the reference value from the $Hash variable. The result is displayed as Hash Valid or Hash Not Valid in green and red, respectively.

At the end of the work, we delete the SSH Session and calculate the duration of work with the Get-CalculateWorkingTime function, which I talked about in the previous post.

The result of the function is shown in the following figure:

Figure 1. The result of the execution of the Check-UploadedFileHash Powershell function

Brief Summary


So, in today’s post, I’ve shared with you some code snippets that demonstrate the strategy and practice of Operations as Code.

I note that you can use this code at your discretion, adding there, for example, verification codes and handling of exceptional situations, etc.

Also, don’t forget that the function requires the presence of the VMware PowerCLI and Posh-SSH.

That’s all for today. Follow the next publications of this direction.

Follow the news until the meeting is on air in a few days.
Sincerely, AIRRA.

This entry was posted in Code, Programming, Technology, Virtualization, VMware and tagged , , , , , , , , , , , , . Bookmark the permalink.