You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:PowerShell结合WinSCP比较目录文件时间戳及密钥算法错误

WinSCP文件时间戳对比脚本及密钥兼容问题解决

问题描述

我是PowerShell脚本开发新手,需要实现通过WinSCP对比本地与远程SFTP服务器目录中文件时间戳的功能,具体需求:

  • 获取用户输入的本地文件路径、远程服务器文件路径
  • 获取用户输入的待比较文件名
  • 对比两者的时间戳并输出结果

尝试编写连接脚本时遇到主机密钥算法不兼容错误,提示:

Couldn't agree a key host algorithm (available rsa-sha2-512, rsa-sha2-256)

WinSCP版本为6.3.1,附尝试的代码:

try
{
  # Load WinSCP .NET assembly
  Add-Type -Path "WinSCPnet.dll"

  # Setup session options
  $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = "example.com"
    UserName = "user"
    Password = "mypassword"
    SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..."
  }

  $session = New-Object WinSCP.Session

  try
  {
    # Connect
    $session.Open($sessionOptions)

    # code for comparing timestamp
  }
  finally
  {
    # Disconnect, clean up
    $session.Dispose()
  }

  exit 0
}
catch
{
  Write-Host "Error: $($_.Exception.Message)"
  exit 1
}

一、主机密钥算法不兼容问题解决

错误原因是指定的SshHostKeyFingerprint使用旧版ssh-rsa算法指纹,但服务器仅支持rsa-sha2-512或rsa-sha2-256这两种SHA2-based的RSA算法。解决步骤:

  1. 获取正确的主机密钥指纹:
    • 打开WinSCP图形客户端,手动连接目标SFTP服务器,在弹出的主机密钥确认窗口中,复制rsa-sha2-256或rsa-sha2-512算法的指纹(格式类似ssh-rsa-sha2-256 256 xx:xx:...)
    • 或用WinSCP命令行获取:
      winscp.com /command "open sftp://user:password@example.com" "exit"
      
      执行后输出会显示服务器提供的密钥指纹,复制对应算法的即可。
  2. 修改脚本配置:
    将SshHostKeyFingerprint的值替换为新获取的指纹,示例:
    SshHostKeyFingerprint = "ssh-rsa-sha2-256 256 AA:BB:CC:DD:EE:...",
    

二、完整的文件时间戳比较脚本

以下是实现需求的完整PowerShell脚本,包含用户输入、SFTP连接、时间戳对比逻辑:

try
{
    # 加载WinSCP .NET组件
    Add-Type -Path "WinSCPnet.dll"

    # 获取用户输入
    $localPath = Read-Host "请输入本地文件目录路径"
    $remotePath = Read-Host "请输入远程服务器文件目录路径"
    $fileName = Read-Host "请输入待比较的文件名"

    # 拼接完整文件路径
    $localFullPath = Join-Path -Path $localPath -ChildPath $fileName
    $remoteFullPath = Join-Path -Path $remotePath -ChildPath $fileName

    # 配置SFTP会话选项
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Sftp
        HostName = "example.com"
        UserName = "user"
        Password = "mypassword"
        # 替换为你获取的新主机密钥指纹
        SshHostKeyFingerprint = "ssh-rsa-sha2-256 256 AA:BB:CC:DD:EE:...",
    }

    $session = New-Object WinSCP.Session

    try
    {
        # 连接SFTP服务器
        $session.Open($sessionOptions)

        # 检查本地文件是否存在
        if (-not (Test-Path -Path $localFullPath -PathType Leaf))
        {
            Write-Host "错误:本地文件 $localFullPath 不存在"
            exit 1
        }

        # 检查远程文件是否存在
        if (-not $session.FileExists($remoteFullPath))
        {
            Write-Host "错误:远程文件 $remoteFullPath 不存在"
            exit 1
        }

        # 获取本地文件时间戳(最后修改时间,UTC)
        $localFileTime = (Get-Item -Path $localFullPath).LastWriteTimeUtc

        # 获取远程文件时间戳(最后修改时间,UTC)
        $remoteFileInfo = $session.GetFileInfo($remoteFullPath)
        $remoteFileTime = $remoteFileInfo.LastWriteTime

        # 对比时间戳并输出结果
        Write-Host "=== 文件时间戳对比结果 ==="
        Write-Host "本地文件:$localFullPath"
        Write-Host "最后修改时间:$localFileTime"
        Write-Host "远程文件:$remoteFullPath"
        Write-Host "最后修改时间:$remoteFileTime"

        if ($localFileTime -eq $remoteFileTime)
        {
            Write-Host "* 时间戳一致"
        }
        elseif ($localFileTime -gt $remoteFileTime)
        {
            Write-Host "* 本地文件更新"
        }
        else
        {
            Write-Host "* 远程文件更新"
        }
    }
    finally
    {
        # 释放会话资源
        $session.Dispose()
    }

    exit 0
}
catch
{
    Write-Host "执行错误:$($_.Exception.Message)"
    exit 1
}

脚本说明

  • 先校验本地和远程文件是否存在,避免无效对比
  • 统一使用UTC时间对比,消除时区差异导致的误差
  • 清晰输出对比结果,明确标注哪个文件更新

内容的提问来源于stack exchange,提问作者Killua11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:50:53