Powershell. Работа с FTP

Давайте разберем несколько основных сценариев работы с FTP с использованием Powershell

  1. Загрузка на FTP
    $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

ftp://contoso.com/folder/

может фактически представлять собой путь

ftp://contoso.com/public_html/files/reports/folder/
  1. Скачать с FTP
    $ftp_uri = 'ftp://contoso.com/folder/'
    $LocalPath = 'C:\temp\ftp\'
    $user = 'user'
    $pass = 'password'
    
    # В отсутствующую папку загрузка не пройдет. Задаем проверку
    if(!(Test-Path $LocalPath)){ New-Item -ItemType directory -Path $LocalPath }
    
    # Получаем список файлов с FTP
    function 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 + $_) )  }
  2. Удалить файл с FTP
    # Удалить файл с 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()
  3. Добавление текста в документ на FTP

    Код практически идентичен варианту с загрузкой на FTP, меняется только используемый метод

    $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,
так как по завершению загрузки, файл не появится на диске до тех пор, пока сессия не будет завершена.
А так же, при инициированном подключении, вы не сможете выполнить новое, и получите ошибку

Возможные ошибки
Исключение при вызове "GetRequestStream" с "0" аргументами: "Невозможно разрешить удаленное имя: 'FILENAME'

Проблема заключается в неправильно заданном формате имени для файла на FTP.

Исключение при вызове "GetRequestStream" с "0" аргументами: "Невозможно соединиться с удаленным сервером"

Проблема, как ни странно, в недоступности вашего сайта.
Выполните Ping, и в случае недоступности сайта, ищите причину возникновения сетевой проблемы.

3 мысли о “Powershell. Работа с FTP”

  1. Спасибо за примеры кода. Однако загрузка на FTP сразу же огорчила, так как при передаче больших файлов они сначала копируются в оперативную память (Get-Content), и ее просто не хватает. Может быть, предложите другой метод?

    1. А «большие», это какого размера?

      Попробуйте использовать вместо Get-Content другую конструкцию:

      $FileContent = [System.IO.File]::ReadAllBytes( $LocalPath + $FileName )

  2. Нашел альтернативное решение по загрузке на FTP без Get-Content

    $SourceFile = Get-ChildItem -Path $LocalPath -Filter $FileName 
    
    # Добавляем новые данные
    # Задаем имя файла который будет создан на 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
    
    $ReadStream = $SourceFile.OpenRead()
    $WriteStream = $FTPRequest.GetRequestStream()
    $ReadStream.CopyTo($WriteStream)
    
    # Закрываем соединение к локальному файлу
    $ReadStream.Close()
    $ReadStream.Dispose()
    
    # Закрываем соединение к удаленному серверу
    $WriteStream.Close()
    $WriteStream.Dispose()

Добавить комментарий

Ваш адрес email не будет опубликован.