Давайте разберем несколько основных сценариев работы с FTP с использованием Powershell
-
Загрузка на FTP
1234567891011121314151617181920212223$ftp_uri = 'ftp://contoso.com/folder/'$FileName = 'Filename.csv'$LocalPath = 'C:\temp\'$user = 'user'$pass = 'password'# Добавляем новые данные# Задаем имя файла который будет создан на FTP$FTPRequest = [System.Net.FtpWebRequest]::Create( $ftp_uri + $FileName )$FTPRequest.Credentials = new-object System.Net.NetworkCredential($user, $pass)# Задаем метод для добавления$FTPRequest.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile$FTPRequest.UseBinary = $true$FTPRequest.UsePassive = $true# Считываем файл на локальном компьютере$FileContent = Get-Content -en byte ( $LocalPath + $FileName )$FTPRequest.ContentLength = $FileContent.Length# Передаем файл на FTP$Run = $FTPRequest.GetRequestStream()$Run.Write($FileContent, 0, $FileContent.Length)# Закрываем соединение$Run.Close()$Run.Dispose()
Обратите внимание что переменная $ftp_uri представляет из себя точку входа, а не конкретный путь.
Потому что каталог в который вы попадете, при подключению к вашему FTP, будет определен настройками вашего FTP аккаунта.
Таким образом, точка входа для $ftp_uri
1 |
ftp://contoso.com/folder/ |
может фактически представлять собой путь
1 |
ftp://contoso.com/public_html/files/reports/folder/ |
-
Скачать с FTP
123456789101112131415161718192021222324$ftp_uri = 'ftp://contoso.com/folder/'$LocalPath = 'C:\temp\ftp\'$user = 'user'$pass = 'password'# В отсутствующую папку загрузка не пройдет. Задаем проверкуif(!(Test-Path $LocalPath)){ New-Item -ItemType directory -Path $LocalPath }# Получаем список файлов с FTPfunction Get-FtpDir ($url, $credentials){$request = [Net.FtpWebRequest]::Create($url)if ($credentials) { $request.Credentials = $credentials }$request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory(New-Object IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd() -split "`r`n"}$webclient = New-Object System.Net.WebClient$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)$webclient.BaseAddress = $ftp_uri# Выполняем загрузку с возможностью фильтрацииGet-FTPDir $ftp_uri $webclient.Credentials |? { $_ -like "*.csv" } | % { $webClient.DownloadFile( $_,$($LocalPath + $_) ) } -
Удалить файл с FTP
123456789# Удалить файл с FTP$user='user'$pass='password'$ftp_uri='ftp://contoso.com/folder/Filename.csv'$request = [System.Net.FtpWebRequest]::create($ftp_uri)$request.Credentials = new-object System.Net.NetworkCredential( $user, $pass )$request.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile$request.GetResponse() -
Добавление текста в документ на FTP
Код практически идентичен варианту с загрузкой на FTP, меняется только используемый метод
1234567891011121314151617181920212223$ftp_uri = 'ftp://contoso.com/folder/'$FileName = 'Filename.csv'$LocalPath = 'C:\temp\'$user = 'user'$pass = 'password'# Добавляем новые данные# Задаем имя файла который будет создан на FTP$FTPRequest = [System.Net.FtpWebRequest]::Create( $ftp_uri + $FileName )$FTPRequest.Credentials = new-object System.Net.NetworkCredential($user, $pass)# Задаем метод для добавления$FTPRequest.Method = [System.Net.WebRequestMethods+Ftp]::AppendFile$FTPRequest.UseBinary = $true$FTPRequest.UsePassive = $true# Считываем файл на локальном компьютере$FileContent = Get-Content -en byte ( $LocalPath + $FileName )$FTPRequest.ContentLength = $FileContent.Length# Передаем файл на FTP$Run = $FTPRequest.GetRequestStream()$Run.Write($FileContent, 0, $FileContent.Length)# Закрываем соединение$Run.Close()$Run.Dispose()
Внимание: Важно не забывать закрыть подключение с FTP,
так как по завершению загрузки, файл не появится на диске до тех пор, пока сессия не будет завершена.
А так же, при инициированном подключении, вы не сможете выполнить новое, и получите ошибку
Возможные ошибки
1 |
Исключение при вызове "GetRequestStream" с "0" аргументами: "Невозможно разрешить удаленное имя: 'FILENAME' |
Проблема заключается в неправильно заданном формате имени для файла на FTP.
1 |
Исключение при вызове "GetRequestStream" с "0" аргументами: "Невозможно соединиться с удаленным сервером" |
Проблема, как ни странно, в недоступности вашего сайта.
Выполните Ping, и в случае недоступности сайта, ищите причину возникновения сетевой проблемы.
Спасибо за примеры кода. Однако загрузка на FTP сразу же огорчила, так как при передаче больших файлов они сначала копируются в оперативную память (Get-Content), и ее просто не хватает. Может быть, предложите другой метод?
А «большие», это какого размера?
Попробуйте использовать вместо Get-Content другую конструкцию:
$FileContent = [System.IO.File]::ReadAllBytes( $LocalPath + $FileName )
Нашел альтернативное решение по загрузке на FTP без Get-Content