使用 PowerShell 通过 FTP 上传文件

问题描述

我正在编写一个监视目录的 Powershell 脚本,当一个文件(或多个)上传到目录中时,它会获取这些文件,将它们复制到另一个文件夹,将它们发送到 FTP 服务器,然后删除来自原始目录的文件

我在连接到 FTP 服务器时遇到问题。我不确定问题是否出在我配置 Web 客户端的方式上,或者问题出在 ftp URI 中有空格而我没有正确转义它们。

代码如下:

$source = "c:/testFtp"

$ftpdestination = "ftp://username:password@ftp.ftpsite.com/folder with space/folder with space"

$webclient = New-Object -TypeName System.Net.WebClient

$files = Get-ChildItem $source
foreach ($file in $files)
{
    Write-Host "Uploading $file"
    try {
        $ftp = "$ftpdestination/$file"
        $uri = New-Object -TypeName System.Uri -ArgumentList $ftp

        $webclient.UploadFile($uri,$source/$file)

    } catch {
        Add-content "$logs" -value "There was an error uploading to ftp"
    }
}
$webclient.dispose()

我曾尝试以多种方式转义文件夹空间,所以我开始认为这不是问题,而且我没有正确配置 Web 客户端。

它也不会经常捕获错误,所以我不相信当 web 客户端上传失败时它会抛出错误。任何帮助表示赞赏!

解决方法

答案:

事实证明 WebClient 连接正确,但 SSL 阻止发送文件。我通过使用 C# 编译和运行脚本发现了这一点,它为我提供了更好的错误处理,因为我是 Powershell 脚本的新手,似乎无法获得良好的错误处理。

经过研究,我找不到通过 WebClient 启用 SSL 的方法,因此我切换到 FtpWebRequest。这是成功的代码(这个 try catch 块似乎没有像我想要的那样记录错误,但该工具现在可以成功地将文件发送到 ftp 服务器:

try {
    $ftp = [System.Net.FtpWebRequest]::Create("$ftpsite/$filename")
    $ftp = [System.Net.FtpWebRequest]$ftp
    $ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
    $ftp.Credentials = new-object System.Net.NetworkCredential("$username","$password")
    $ftp.UseBinary = $true
    $ftp.UsePassive = $true
    $ftp.EnableSSL = $true  #<-----------------This was the line that made this work
    $ftp.KeepAlive = $false
    # read in the file to upload as a byte array
    $content = [System.IO.File]::ReadAllBytes("$source/$file")
    $ftp.ContentLength = $content.Length
    # get the request stream,and write the bytes into it
    $rs = $ftp.GetRequestStream()
    $rs.Write($content,$content.Length)
    # be sure to clean up after ourselves
    $rs.Close()
    $rs.Dispose()

    Write-Host "Successfully uploaded: $source/$file"
    Copy-Item "$source/$file" -Destination "$copydestination"
    Remove-Item "$source/$file"
    $logline = "$(Get-Date),Added File: $file to $copydestination"
    Add-content "$logs" -value $logline 
    } catch {
        $res = $ftp.GetResponse()
        Add-content "$logs" -value "There was an error: $res.StatusCode" 
        Write-Error -Message "There was an error." -ErrorAction Stop
    }