PowerShell 使用 ssh 驗證本地與遠端檔案的 SHA256 是否一致
要驗證傳輸到底有沒有傳對用的函式
# 獲取遠端檔案的雜湊值
function Get-RemoteFileHash {
[CmdletBinding()]
param (
# 遠端檔案路徑
[Parameter(Mandatory, ValueFromPipeline)]
[string]$Path,
# 遠端登入資訊
[Parameter(Mandatory)]
[string]$RemoteLoginInfo,
# 遠端私鑰
[Parameter(Mandatory)]
[string]$IdentityFile,
# 遠端作業系統
[Parameter(Mandatory)]
[ValidateSet('Windows', 'Linux')]
[string]$RemoteOS
) begin {
# 檢查私鑰是否存在
if (-not (Test-Path $IdentityFile)) {
Write-Error "Cannot find path '$IdentityFile' because it does not exist."
}
# 定義不同作業系統的雜湊命令
$hashCommands = @{
'Windows' = "powershell `"(Get-FileHash -Path ([WildcardPattern]::Escape('$Path')) -Algorithm SHA256 -EA 1).Hash`""
'Linux' = "sha256sum '$Path' 2>&1 >/dev/null && sha256sum '$Path' | cut -d' ' -f1 | tr '[:lower:]' '[:upper:]'"
}
# SSH 連線參數設定
$sshParams = @(
'-oBatchMode=yes'
"-oIdentityFile=$IdentityFile"
$RemoteLoginInfo
)
} process {
# 執行遠端雜湊命令
$hash = & ssh @sshParams $hashCommands[$RemoteOS] 2>&1
# 檢查 ssh 命令是否成功
if ($LASTEXITCODE -ne 0) {
Write-Error "ssh command failed: $hash"
return $null
}
# 檢查雜湊值格式是否正確 (SHA-256 應為 64 個十六進制字符)
if (-not ($hash -match '^[A-F0-9]{64}$')) {
Write-Error "The hash value '$hash' returned from command '$hashCommand' is not a valid SHA-256 format"
return $null
}
return $hash
}
}
使用範例
# SSH 連線設定
$remoteLoginInfo = "chg@192.168.3.53"
$identityFile = "${env:USERPROFILE}\.ssh\id_ed25519"
$remoteOS = "Linux"
$remotePath = "/home/chg/work/Tester.bats"
Get-RemoteFileHash $remotePath `
-RemoteLoginInfo $remoteLoginInfo `
-IdentityFile $identityFile `
-RemoteOS $remoteOS
執行完會自動返回遠端檔案的哈希值,再來比較本地端即可知道是否一致了。
如果是要從 sftp 指令獲取位址可以參考這個
# 解析 SFTP 命令
function ParseSftpCommandPath {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline)]
[string]$CommandText
)
process {
# 跳過空行和註解
if (-not ($CommandText -match '\S') -or $CommandText -match '^\s*#') { return }
# 解析命令行
$tokens = [regex]::Matches(
$CommandText.Trim(), '"[^"]+"|[^\s"]+'
).Value.Trim('"')
# 獲取遠端檔案路徑
if ($tokens[0] -in 'get','put') {
$paths = $tokens[1..($tokens.Count-1)].Where({ $_ -notmatch '^-' })
$idx = @{
'get' = @{local=-1; remote=0}
'put' = @{local=0; remote=-1}
}[$tokens[0]]
[PSCustomObject]@{
Command = $tokens[0]
LocalPath = $paths[$idx.local]
RemotePath = $paths[$idx.remote]
}
}
}
} # "get /home/chg/work/Tester.bats Tester.bats" | ParseSftpCommandPath
沒有留言:
張貼留言