Verify checksum of a remote file against a local file over SFTP/FTP protocol

The following script uses WinSCP .NET assembly from a PowerShell script. If you have another preferred language, you can easily translate it.

The script is distributed in WinSCP installer as a WinSCP extension.

To run the script manually use:

powershell.exe -File C:\path\VerifyFileChecksum.ps1 -sessionUrl "sftp://username:password;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/" -localPath "C:\local\path\file.dat" -remotePath "/remote/path/file.dat"

Advertisement

Note that calculation of a remote file checksum is supported with SFTP and FTP protocols only, subject to support of respective protocol extension.

# @name         Verify &Checksum
# @command      powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" ^
#                   -sessionUrl "!E" -localPath "!^!" -remotePath "!/!" -pause ^
#                   -sessionLogPath "%SessionLogPath%"
# @description  Compares checksums of the selected local and remote file
# @flag         RemoteFiles
# @version      6
# @homepage     https://winscp.net/eng/docs/library_example_verify_file_checksum
# @require      WinSCP 5.16
# @option       SessionLogPath -config sessionlogfile
# @optionspage  https://winscp.net/eng/docs/library_example_verify_file_checksum#options
 
param (
    # Use Generate Session URL function to obtain a value for -sessionUrl parameter.
    $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/",
    [Parameter(Mandatory = $True)]
    $localPath,
    [Parameter(Mandatory = $True)]
    $remotePath,
    $sessionLogPath = $Null,
    [Switch]
    $pause
)
 
try
{
    Write-Host $localPath
 
    # Calculate local file checksum
    $sha1 = [System.Security.Cryptography.SHA1]::Create()
    $localStream = [System.IO.File]::OpenRead($localPath)
    $localChecksum = [System.BitConverter]::ToString($sha1.ComputeHash($localStream))
 
    Write-Host $localChecksum
    
    # Load WinSCP .NET assembly
    $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot }
    Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.ParseUrl($sessionUrl)
 
    $session = New-Object WinSCP.Session
 
    try
    {
        $session.SessionLogPath = $sessionLogPath
 
        # Connect
        $session.Open($sessionOptions)
        
        Write-Host $remotePath
 
        # Calculate remote file checksum
        $remoteChecksumBytes = $session.CalculateFileChecksum("sha-1", $remotePath)
        $remoteChecksum = [System.BitConverter]::ToString($remoteChecksumBytes)
        Write-Host $remoteChecksum
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    # Compare cheksums
    if ($localChecksum -eq $remoteChecksum)
    {
        Write-Host "Match"
        $result = 0
    }
    else
    {
        Write-Host "Does NOT match"
        $result = 1
    }
}
catch
{
    Write-Host "Error: $($_.Exception.Message)"
    $result = 1
}
 
# Pause if -pause switch was used
if ($pause)
{
    Write-Host "Press any key to exit..."
    [System.Console]::ReadKey() | Out-Null
}
 
exit $result

Advertisement

Options

In the Session log file you can specify a path to a session log file.

In the Keyboard shortcut, you can specify a keyboard shortcut for the extension.

Last modified: by martin