使用PowerShell中的WinSCP .NET程序集从FTP / SFTP服务器上的文件夹集中下载文件和电子邮件结果

用户91

我有正在使用的PowerShell脚本。导入CSV文件可获取源路径和目标路径。目的是将文件从SFTP / FTP服务器移至目标位置并发送电子邮件报告。

任务计划程序将每小时运行一次此代码。如果有新文件,则将发送电子邮件。

差不多完成了,但是缺少两件事:

  • 检查文件是否已经存在,并且正文电子邮件似乎为空:出现以下错误:无法验证参数“正文”上的参数。参数为null或为空。提供一个不为null或为空的参数,然后重试该命令。

  • 我想要一些有关如何检查文件是否存在以及如果将新文件删除并复制到目标列表时如何获得此电子邮件的帮助

$SMTPBody = ""

$SMTPMessage  = @{
  "SMTPServer" = ""
  "From" = ""
  "To" = ""
  "Subject" = "New File"
}
try {
  # Load WinSCP .NET assembly
  Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"

  # Setup session options
  $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::sftp
    HostName = ""
    UserName = ""
    Password = ""
    PortNumber = "22"
    FTPMode = ""
    GiveUpSecurityAndAcceptAnySshHostKey = $true
  }
  $session = New-Object WinSCP.Session
  try
  {
    # Connect
    $session.Open($sessionOptions)
    # Download files
    $transferOptions = New-Object WinSCP.TransferOptions
    $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary

    Import-Csv -Path "D:\FILESOURCE.csv" -ErrorAction Stop |  foreach {

      $synchronizationResult = $session.SynchronizeDirectories(
        [WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)
      $synchronizationResult.Check()

      foreach ($download in $synchronizationResult.Downloads ) {
        Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
        $SMTPBody +=
          "`n Files: $($download.FileName -join ',    ') `n" +
          "Current Location: $($_.Destination)`n"
        Send-MailMessage @SMTPMessage  -Body $SMTPBody
      }

      $transferResult =
        $session.GetFiles($_.Source, $_.Destination, $False, $transferOptions)
      #Find the latest downloaded file
      $latestTransfer =
        $transferResult.Transfers |
        Sort-Object -Property @{ Expression = { (Get-Item $_.Destination).LastWriteTime }
        } -Descending |Select-Object -First 1
    }

    if ($latestTransfer -eq $Null) {
      Write-Host "No files found."
      $SMTPBody += "There are no new files at the moment"
    }
    else
    {
      $lastTimestamp = (Get-Item $latestTransfer.Destination).LastWriteTime
      Write-Host (
        "Downloaded $($transferResult.Transfers.Count) files, " +
        "latest being $($latestTransfer.FileName) with timestamp $lastTimestamp.")
      $SMTPBody += "file : $($latestTransfer)"
    }

    Write-Host "Waiting..."
    Start-Sleep -Seconds 5
  }  
  finally
  {
    Send-MailMessage @SMTPMessage  -Body  $SMTPBody
    # Disconnect, clean up
    $session.Dispose()
  }
}
catch
{
  Write-Host "Error: $($_.Exception.Message)"
}
马丁·普里克里(Martin Prikryl)

我相信您的代码有比您想象的更多的问题。

  • SynchronizeDirectories和的组合GetFiles是可疑的。您首先只能通过下载新文件SynchronizeDirectories,然后通过下载所有文件GetFiles我不认为你想要那样。
  • 发生任何错误时,.Check呼叫都会引发,您不会将错误收集到报告中。
  • 您继续通过Send-MailMessageforeach循环发送部分报告

这是我对您的问题的看法,希望我已正确理解您要实现的目标:

$SMTPBody = ""

Import-Csv -Path "FILESOURCE.csv" -ErrorAction Stop |  foreach {

    Write-Host "$($_.Source) => $($_.Destination)"
    $SMTPBody += "$($_.Source) => $($_.Destination)`n"

    $synchronizationResult =
        $session.SynchronizeDirectories(
            [WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)

    $downloaded = @()
    $failed = @()
    $latestName = $Null
    $latest = $Null
    foreach ($download in $synchronizationResult.Downloads)
    {
        if ($download.Error -eq $Null)
        {
            Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
            $downloaded += $download.FileName
            $ts = (Get-Item $download.Destination).LastWriteTime
            if ($ts -gt $latest)
            {
                $latestName = $download.FileName;
                $latest = $ts
            }
        }
        else
        {
            Write-Host "File $($download.FileName) download failed" -ForegroundColor Red
            $failed += $download.FileName
        }
    }

    if ($downloaded.Count -eq 0)
    {
        $SMTPBody += "No new files were downloaded`n"
    }
    else
    {
        $SMTPBody += 
            "Downloaded $($downloaded.Count) files:`n" +
            ($downloaded -join ", ") + "`n" +
            "latest being $($latestName) with timestamp $latest.`n"
    }

    if ($failed.Count -gt 0)
    {
        $SMTPBody += 
            "Failed to download $($failed.Count) files:`n" +
            ($failed -join ", ") + "`n"
    }

    $SMTPBody += "`n"
}

它将为您提供如下报告:

/source1 => C:\dest1`
Downloaded 3 files:
/source1/aaa.txt, /source1/bbb.txt, /source1/ccc.txt
latest being /source1/ccc.txt with timestamp 01/29/2020 07:49:07.

/source2 => C:\dest2
Downloaded 1 files:
/source2/aaa.txt
latest being /source2/aaa.txt with timestamp 01/29/2020 07:22:37.
Failed to download 1 files:
/source2/bbb.txt

本文收集自互联网,转载请注明来源。

如有侵权,请联系de[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档