当前位置: 首页 > 知识库问答 >
问题:

PowerShell连接到FTP服务器并获取文件

何高歌
2023-03-14
$ftpServer = "ftp.example.com"
$username ="validUser"
$password ="myPassword"
$localToFTPPath = "C:\ToFTP"
$localFromFTPPath = "C:\FromFTP"
$remotePickupDir = "/Inbox"
$remoteDropDir = "/Outbox"
$SSLMode = [AlexPilotti.FTPS.Client.ESSLSupportMode]::ClearText
$ftp = new-object "AlexPilotti.FTPS.Client.FTPSClient"
$cred = New-Object System.Net.NetworkCredential($username,$password)
$ftp.Connect($ftpServer,$cred,$SSLMode) #Connect
$ftp.SetCurrentDirectory($remotePickupDir)
$ftp.GetFiles($localFromFTPPath, $false) #Get Files

这是我从FTP服务器导入文件的脚本。< br >但是我不确定什么是< code>remotePickupDir以及这个脚本是否正确?

共有3个答案

颛孙天宇
2023-03-14

远程选取目录路径应该是您要访问的 ftp 服务器上的确切路径。这是从服务器下载文件的脚本。您可以使用 SSL 模式添加或修改。

#ftp server 
$ftp = "ftp://example.com/" 
$user = "XX" 
$pass = "XXX"
$SetType = "bin"  
$remotePickupDir = Get-ChildItem 'c:\test' -recurse
$webclient = New-Object System.Net.WebClient 

$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)  
foreach($item in $remotePickupDir){ 
    $uri = New-Object System.Uri($ftp+$item.Name) 
    #$webclient.UploadFile($uri,$item.FullName)
    $webclient.DownloadFile($uri,$item.FullName)
}
孙泉
2023-03-14

下面是将所有文件(带通配符或文件扩展名)从FTP站点下载到本地目录的完整工作代码。设置变量值。

    #FTP Server Information - SET VARIABLES
    $ftp = "ftp://XXX.com/" 
    $user = 'UserName' 
    $pass = 'Password'
    $folder = 'FTP_Folder'
    $target = "C:\Folder\Folder1\"

    #SET CREDENTIALS
    $credentials = new-object System.Net.NetworkCredential($user, $pass)

    function Get-FtpDir ($url,$credentials) {
        $request = [Net.WebRequest]::Create($url)
        $request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory
        if ($credentials) { $request.Credentials = $credentials }
        $response = $request.GetResponse()
        $reader = New-Object IO.StreamReader $response.GetResponseStream() 
        while(-not $reader.EndOfStream) {
            $reader.ReadLine()
        }
        #$reader.ReadToEnd()
        $reader.Close()
        $response.Close()
    }

    #SET FOLDER PATH
    $folderPath= $ftp + "/" + $folder + "/"

    $files = Get-FTPDir -url $folderPath -credentials $credentials

    $files 

    $webclient = New-Object System.Net.WebClient 
    $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) 
    $counter = 0
    foreach ($file in ($files | where {$_ -like "*.txt"})){
        $source=$folderPath + $file  
        $destination = $target + $file 
        $webclient.DownloadFile($source, $target+$file)

        #PRINT FILE NAME AND COUNTER
        $counter++
        $counter
        $source
    }
濮阳安澜
2023-03-14

问题中使用的AlexFTPS库似乎已经失效(自2011年以来未更新)。

您可以尝试在不使用任何外部库的情况下实现此功能。但不幸的是,.NET Framework和PowerShell都不明确支持下载目录中的所有文件(更不用说递归文件下载)。

您必须自己实现:

  • 列出远程目录
  • 迭代条目,下载文件(并选择性地递归到子目录中 - 再次列出它们等)

棘手的部分是识别子目录中的文件。没有办法使用 .NET 框架(FtpWeb 请求Web 客户端)以可移植的方式执行此操作。不幸的是,.NET 框架不支持 MLSD 命令,这是在 FTP 协议中检索包含文件属性的目录列表的唯一可移植方法。另请参阅检查 FTP 服务器上的对象是文件还是目录。

您的选项包括:

  • 如果您知道目录不包含任何子目录,请使用ListDirectory方法(NLSTFTP命令),只需将所有“名称”作为文件下载即可
  • 对文件名执行操作,该操作对于文件肯定会失败,对于目录肯定会成功(反之亦然)。一、 你可以试着下载“名字”
  • 您可能很幸运,在您的特定情况下,您可以通过文件名区分目录中的文件(即所有文件都有扩展名,而子目录没有扩展名)
  • 您使用一个长目录列表(LISTcommand=ListDirectoryDetails方法)并尝试解析特定于服务器的列表。许多FTP服务器使用*nix样式的列表,您可以通过条目开头的d来标识目录。但许多服务器使用不同的格式。下面的示例使用了这种方法(假定为*nix格式)
function DownloadFtpDirectory($url, $credentials, $localPath)
{
    $listRequest = [Net.WebRequest]::Create($url)
    $listRequest.Method =
        [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
    $listRequest.Credentials = $credentials
    
    $lines = New-Object System.Collections.ArrayList

    $listResponse = $listRequest.GetResponse()
    $listStream = $listResponse.GetResponseStream()
    $listReader = New-Object System.IO.StreamReader($listStream)
    while (!$listReader.EndOfStream)
    {
        $line = $listReader.ReadLine()
        $lines.Add($line) | Out-Null
    }
    $listReader.Dispose()
    $listStream.Dispose()
    $listResponse.Dispose()

    foreach ($line in $lines)
    {
        $tokens = $line.Split(" ", 9, [StringSplitOptions]::RemoveEmptyEntries)
        $name = $tokens[8]
        $permissions = $tokens[0]

        $localFilePath = Join-Path $localPath $name
        $fileUrl = ($url + $name)

        if ($permissions[0] -eq 'd')
        {
            if (($name -ne ".") -and ($name -ne ".."))
            {
                if (!(Test-Path $localFilePath -PathType container))
                {
                    Write-Host "Creating directory $localFilePath"
                    New-Item $localFilePath -Type directory | Out-Null
                }

                DownloadFtpDirectory ($fileUrl + "/") $credentials $localFilePath
            }
        }
        else
        {
            Write-Host "Downloading $fileUrl to $localFilePath"

            $downloadRequest = [Net.WebRequest]::Create($fileUrl)
            $downloadRequest.Method =
                [System.Net.WebRequestMethods+Ftp]::DownloadFile
            $downloadRequest.Credentials = $credentials

            $downloadResponse = $downloadRequest.GetResponse()
            $sourceStream = $downloadResponse.GetResponseStream()
            $targetStream = [System.IO.File]::Create($localFilePath)
            $buffer = New-Object byte[] 10240
            while (($read = $sourceStream.Read($buffer, 0, $buffer.Length)) -gt 0)
            {
                $targetStream.Write($buffer, 0, $read);
            }
            $targetStream.Dispose()
            $sourceStream.Dispose()
            $downloadResponse.Dispose()
        }
    }
}

使用以下函数:

$credentials = New-Object System.Net.NetworkCredential("user", "mypassword") 
$url = "ftp://ftp.example.com/directory/to/download/"
DownloadFtpDirectory $url $credentials "C:\target\directory"

该代码是从我的 C# 示例转换而来的,C# 通过 FTP 下载所有文件和子目录。

如果要避免在解析特定于服务器的目录列表格式时出现问题,请使用支持 MLSD 命令和/或分析各种 LIST 列表格式的第三方库。理想情况下,支持从目录下载所有文件,甚至递归下载。

例如,使用 WinSCP .NET 程序集,您可以通过对会话的一次调用来下载整个目录:

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

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "ftp.example.com"
    UserName = "user"
    Password = "mypassword"
}

$session = New-Object WinSCP.Session

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

    # Download files
    $session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check()
}
finally
{
    # Disconnect, clean up
    $session.Dispose()
}    

在内部,如果服务器支持,则使用 MLSD 命令。如果没有,它将使用 LIST 命令并支持数十种不同的列表格式

<代码>进程。默认情况下,GetFiles方法是递归的。

(我是WinSCP的作者)

 类似资料:
  • 我使用Sabre DAV在PHP中实现了一个webdav目录,用于我的网站(Application Server Webinterface)。 对于这个网站,我现在使用C#编写了一个TCP套接字,它运行在另一个服务器上(实际上它在同一个数据中心,但从理论上讲,它在另一个半球上)。 我想连接我的网络Dav到我的套接字的FTP服务器,这意味着文件监听,下载,上传。用户只能连接到一个服务。想象一下,我的

  • --状态:连接到10.10.10.04:21... 状态:连接已建立,正在等待欢迎消息... 状态:正在初始化TLS... 状态:正在验证证书... 状态:TLS连接已建立。 状态:已登录 状态:正在检索目录列表... 状态:“/”的目录列表成功

  • python连接ftp服务器,获取指定目录下的文件并下载,如果连接的时候指定utf-8编码,但是ftp服务器文件包含了非utf8编码的文件(ftp服务器上文件可能从windows上传存在gbk编码的文件),这样以下程序会报错'utf-8' codec can't decode byte 0xc6 in position 304: invalid continuation byte,除了限制上传的时

  • 我写了一个JAVA代码,使用Apache Commons Net FTPClient遍历FTP位置,并在Excel文件中获得输出。 我正在使用commons-net-3.0.1。罐子我做了一些测试 并发送,但仍会收到相同的错误。 我要做的就是遍历一个目录,如果找到了文件,就在excel中获取文件名和文件更新日期,如果找到了目录,就进入目录,直到再次找到文件。 请帮助并询问是否需要任何其他信息。我是

  • 我一直在使用spring integration,我想连接多个ftp服务器来从远程位置检索文件,谁能给我一个好的例子,如何使用spring integration连接多个ftp服务器 先谢谢你,Udeshika

  • 我试图使用System.net.ftpWebResponse连接到FTP服务器,但遇到了TLS问题; 如果我使用此配置: 我得到这个错误: 正确的配置是什么? ------更新我不知道它是否有任何相关性,但我尝试了一个工具来检查ftp服务器,我得到了这个;我真的不知道这些意味着什么 通过NPN+ALPN以外的套接字测试协议 您不应继续,因为未检测到任何协议。如果你真的真的想,说“YES”-->YE