$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サーバーからファイルをインポートするために取得したスクリプトです。
ただし、remotePickupDir
とは何かわかりません。このスクリプトは正しいですか?
リモートピックディレクトリパスは、アクセスしようとしているFTPサーバー上の正確なパスである必要があります。ここに、サーバーからファイルをダウンロードするスクリプトを示します。SSLModeで追加または変更できます。
#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)
}
質問で使用されたAlexFTPSライブラリは死んでいるようです(2011年以降更新されていません)。
または、外部ライブラリなしでこれを実装することもできます。ただし、残念ながら、.NET FrameworkもPowerShellも、ディレクトリ内のすべてのファイルのダウンロードを明示的にサポートしていません(再帰的なファイルのダウンロードのみを許可します)。
自分で実装する必要があります。
トリッキーな部分は、サブディレクトリからファイルを識別することです。 .NETフレームワーク(FtpWebRequest
またはWebClient
)で移植可能な方法でそれを行う方法はありません。残念ながら、.NETフレームワークはMLSD
コマンドをサポートしていません。これは、FTPプロトコルのファイル属性を使用してディレクトリリストを取得する唯一のポータブルな方法です。 FTPサーバー上のオブジェクトがファイルかディレクトリかを確認する も参照してください。
オプションは次のとおりです。
ListDirectory
メソッド(NLST
FTPコマンド)を使用して、すべての「名前」をファイルとしてダウンロードします。LIST
command = 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 (!(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#FTPを介してすべてのファイルとサブディレクトリをダウンロード のC#の例から翻訳されています。
サーバー固有のディレクトリリスト形式の解析に関する問題を回避する場合は、MLSD
コマンドをサポートするサードパーティライブラリを使用するか、さまざまなLIST
リスト形式を解析します。そして理想的には、ディレクトリからのすべてのファイルのダウンロードまたは再帰的なダウンロードをサポートします。
たとえば、 WinSCP .NET Assembly の場合、 Session.GetFiles
を1回呼び出すだけでディレクトリ全体をダウンロードできます。
# 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()
}
サーバーでサポートされている場合、内部的に、WinSCPはMLSD
コマンドを使用します。そうでない場合は、LIST
コマンドを使用し、多数の異なるリスト形式をサポートします。
Session.GetFiles
method はデフォルトで再帰的です。
(私はWinSCPの著者です)
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
}
remotePickupDir
は、ftpサーバー上の移動先のフォルダーです。 「このスクリプトは正しい」という限り、それは機能しますか?それが動作する場合、それは正しいです。動作しない場合は、どのエラーメッセージまたは予期しない動作が発生しているのかをお知らせください。サポートを提供させていただきます。