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

如何在PowerShell的WinSCP SSH脚本中实现双凭证自动重试登录?

实现方案

核心逻辑为预先定义两组账号凭证,通过循环遍历优先使用第一组账号发起连接,捕获认证失败异常后自动切换第二组重试,SSH和WinSCP复用同一组验证通过的凭证,避免两次连接使用不同账号的冲突问题。

修改后的完整代码

if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))  
{  
  $arguments = "& '" +$myinvocation.mycommand.definition + "'"
  Start-Process powershell -Verb runAs -ArgumentList $arguments
  Break
}

Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
 
$db = import-csv -Path "C:\Program Files (x86)\WinSCP\db.csv"
 
$inputID = Read-Host -Prompt "ID"
 
$entry = $db | where-Object {$_.HostName  -eq  $inputID}

if ($inputID -eq $entry.HostName){
    "$inputID Ok!"
}
else{
    "$inputID nu exista in baza de date!"
    $title    = 'Title'
    $question = 'Doriti sa introduceti un ID nou in Baza de Date?'
    $choices  = '&Yes', '&No'

    $decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
    if ($decision -eq 0) {
        Write-Host 'confirmed'
        $ID = Read-Host -Prompt "Introduceti ID"
        $IP = Read-Host -Prompt "Introduceti IP"
        $wrapper = New-Object PSObject -Property @{ HostName = $ID; IP = $IP }
        Export-Csv -Append -InputObject $wrapper -Path "C:\Program Files (x86)\WinSCP\db.csv" -NoTypeInformation -Force 
        $dbTrimmer = Get-Content -Path "C:\Program Files (x86)\WinSCP\db.csv"
        $dbTrimmer.Replace('","',',').TrimStart('"').TrimEnd('"') | Out-File "C:\Program Files (x86)\WinSCP\db.csv" -Force -Confirm:$false
        Exit
    }
    else{
        Write-Host 'No'
        Exit
    }
}

Write-Host "IP:" $entry.IP

# 配置双组账号凭证,第一组优先使用,请替换为实际账号密码
$credPairs = @(
    @{ User = "user1"; Password = "pass1" },
    @{ User = "user2"; Password = "pass2" }
)
$validCred = $null
$sessionID = $null
$Command = "C:\Info.exe"

# 遍历两组凭证尝试SSH连接
foreach ($pair in $credPairs) {
    $secpasswd = ConvertTo-SecureString $pair.Password -AsPlainText -Force
    $Credentials = New-Object System.Management.Automation.PSCredential($pair.User, $secpasswd)
    try {
        Get-SSHTrustedHost | Remove-SSHTrustedHost -ErrorAction SilentlyContinue
        $sessionID = New-SSHSession -ComputerName $entry.IP -Credential $Credentials -AcceptKey:$true -ErrorAction Stop
        $validCred = $pair
        Write-Host "使用账号$($pair.User) SSH连接成功"
        break
    } catch {
        Write-Host "使用账号$($pair.User) SSH连接失败:$_"
    }
}
# 两组账号均认证失败直接终止脚本
if (-not $validCred) {
    Write-Host "两组账号均认证失败,脚本终止运行"
    Exit 1
}

Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command

# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = $entry.IP
    UserName = $validCred.User
    Password = $validCred.Password
    GiveUpSecurityAndAcceptAnySshHostKey = "true"
}
 
$session = New-Object WinSCP.Session

$file = "Dev.log", "Info.dat"
$localPath = "E:\Arhive\*" 
$remotePath = "/C:/Program Files/Dev.log", "/C:/Program File/Info.dat"

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

    # Check exists files
    foreach ($remotePath in $remotePath)
    {
        if ($session.FileExists($remotePath))
        {
            Write-Host "Fisierul $remotePath exista"
            # Transfer files
            $session.GetFiles($remotePath, $localPath).Check()
        }
        else
        {
            Write-Host "Fisierul $remotePath NU exista"
        }
    }
}
finally {
    $session.Dispose()
}

foreach ($file in "E:\loguri\Dev.log", "E:\loguri\Info.dat") {
    if (Test-Path $file) {
        Compress-Archive $file -DestinationPath "E:\Arhive\$inputID.zip" -Update
        Remove-Item $file
    }
}

# Stergere fisiere din Arhive mai vechi de 60 minute
$Files = get-childitem 'E:\Arhive' | Where-Object PSIsContainer -eq $false
$LimitTime = (Get-Date).AddMinutes(-60)
$Files | ForEach-Object {
    if ($_.CreationTime -lt $LimitTime -and $_.LastWriteTime -lt $LimitTime) {
        Remove-Item -Path $_.FullName -Force
        Write-Host "Am sters $Files pentru ca sunt mai vechi de $LimitTime !"
     }
}

注意事项

  • 请提前替换代码中$credPairs里的两组账号密码为实际业务值
  • 原代码中SFTP拉取路径/C:/Program File/Info.dat存在拼写缺漏,建议根据实际路径修正
  • 若需要对非认证类异常(如IP不可达、端口未开放)也增加重试逻辑,可自行调整异常判断规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:36:03