PowerShell работа с FTP сервером

Рейтинг:   / 2
ПлохоОтлично 

Метод 1. Одна из полезных и удобных особенностей PowerShell – возможность прозрачно взаимодействовать с утилитами командной строки.

В Windows досточно много утилит командной строки, которые уже много лет служат верой и правдой. Многие  утилиты хорошо известны и широко используются. Некоторые решают свою задачу быстро и эффективно. Cовершенно неоправдано ожидать, что PowerShell заменит их сразу и полностью. В ряде случаев такая замена вообще неоправдана. Хорошо, что PowerShell не требует от нас переписывать существующие утилиты на .NET Framework и позволяет использовать всю их мощь.

 

Одна из таких утилит ftp.exe Утилита специфическая и по современным понятиям неудобная. Но она стандартная и администратор может ее использовать при необходимости на любой системе без лишних усилий. Чтобы несколько уменьшить неуклюжесть интерфейса утилиты ftp.exe , используем PowerShell.

Конечно мы не будем делать универсальную обертку: просто продемонстрируем технику и за одно решим вполне практическую задачу копирования списка файлов с ftp-сервера: сделать это стандартными командами вручную непросто (написать 5 команд get еще можно, а 15 уже утомительно).

Для начала создадим список команд в переменной (каждая команда пишется на новой строке!):

1
2
3
4
5
$FileList = "open 17.17.17.21
user USERNAME PASSWORD
binary
cd DIRECTORYNAME
mdir * -" | ftp -i -n | where {$_.Trim() -ne "" }

 

В результате получим листинг нужной директории. Обратите внимание, что использована команда “mdir * - “ – звездочка, пробел, минус. Далее убраны пустые строки. Для конкретного ftp-сервера возможно придется убрать иной мусор.

Получив список файлов, мы можем использовать PowerShell для его предварительной обработки и фильтрации, чтобы выбрать нужные нам файлы для последующего копирования, например за определенную дату:

1
$FileList = $FileList | Where {-not $_.StartsWith("d")} | Where {$_.Contains("Dec 22  2005")} | %{ $_.SubString(49) }

 

Тут сначала убраны директории, затем выбраны файлы за определенную дату, а потом  вырезаны имена файлов.

Теперь скопируем эти файлы на локальную машину:

1
2
3
4
5
6
7
$cmd = » open 17.17.17.21
user USERNAME PASSWORD
binary
cd DIRECTORYNAME
» +
($FileList | %{ «get «»$_»"`n» })
$cmd | ftp -i –n

 

Как видите утилита ftp принимает команды через стандартный поток ввода и выдает результат на стандартный поток вывода. Эта ее особенность использована в приведенном примере.

Примечание.Некоторые утилиты не могут принимать команды через стандартный поток, но могут принимать команды из файла. В этом случае нам придется создать вспомогательный файл команд. Аналогичная ситуация может возникнуть с выводом результатов в файл.

Конечно приведенную технику можно использовать не только для загрузки файлов, но и для выгрузки на сервер: достаточно изменить команду get на команду put.

Метод 2. Другой метод работы с FTP сервером – использовать средства  .NET Framework.

Получить список файлов (DIR):

1
2
3
4
5
6
7
8
9
10
11
12
$server = «17.17.17.21″
$filename = «DIRECTORY»
$url = ftp://$server/$filename
[System.Net.FtpWebRequest]$WR = [System.Net.WebRequest]::Create($url)
$WR.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails
$WR.Proxy = $null
$WR.Credentials = New-Object System.Net.NetworkCredential(«USERNAME», «PASSWORD»)
$WRStream = $WR.GetResponse();
$responseStream = $WRStream.GetResponseStream()
$readStream = new-object System.IO.StreamReader($responseStream, [System.Text.Encoding]::UTF8)
$FileList =$readStream.ReadToEnd()
$FileList = $FileList.Split(«`n`r»)

Примечание. Получить список методов для запросов:

1
[System.Net.WebRequestMethods+FTP].GetMembers() | ft Name

Отфильтровать список файлов и получить только нужные файлы:

1
$FileList = $FileList | Where {-not $_.StartsWith("d")} | Where {$_.Contains("Dec 22  2005")} | %{ $_.SubString(49) }

Загрузить файлы по сформированному списку:

1
2
3
4
5
6
7
8
9
10
11
$FileList | % {
[System.Net.FtpWebRequest]$WR = [System.Net.WebRequest]::Create($url+»/$_»)
$WR.Method = [System.Net.WebRequestMethods+FTP]::DownloadFile
$WR.Proxy = $null
$WR.UseBinary = $True
$WR.Credentials = New-Object System.Net.NetworkCredential(«USERNAME», «PASSWORD»)
$WRStream = $WR.GetResponse()
$responseStream = $WRStream.GetResponseStream()
$readStream = new-object System.IO.StreamReader($responseStream, [System.Text.Encoding]::UTF8)
$a=$readStream.ReadToEnd()
Out-File -FilePath $_ -inputobject $a }

Обратная задача – выгрузка файлов по списку на сервер (не тестировано):

1
2
3
4
5
6
7
8
9
10
11
12
13
$FileList | % {
[System.Net.FtpWebRequest]$WR = [System.Net.WebRequest]::Create($url+»/$_»)
$WR.Method = [System.Net.WebRequestMethods+FTP]::UploadFile
$WR.Proxy = $null
$WR.UseBinary = $True
$WR.Credentials = New-Object System.Net.NetworkCredential(«USERNAME», «PASSWORD»)
$WRStream = $WR.GetResponse()
$responseStream = $WRStream.GetResponseStream()
$WriteStream = new-object System.IO.StreamWriter($responseStream, [System.Text.Encoding]::UTF8)
Get-Content $_ | % {$WriteStream.WriteString($_)
$WriteStream.Close()
$responseStream.Close()
$WRStream.Close()}

Загрузку одиночного файла можно выполнить более экономным методом. Для этого можно применить класс  WebClient Class:

1
2
3
4
5
6
7
8
$WC = new-object System.Net.WebClient
$server = «17.17.17.21″
$filename = «DIRECTORY/FILENAME»
$url = «ftp://$server/$filename»
$WC.Proxy = $null
$Wc.Credentials = New-Object System.Net.NetworkCredential(«USERNAME», «PASSWORD»)
$localfile = «LOCALFILENAME»
$WC.DownloadFile($url,$localfile)

Для выгрузки файла на сервер надо поменять последнюю строку:

1
$WC. UploadFile($url,$localfile)

Метод 3. Загрузить и установить какое-нибудь дополнение к PowerShell для работы с сетью. Есть коммерческие варианты. Есть бесплатные (Indy). Примеры смотрите в самих пакетах.

Заключение. Как видите, написание кода несколько более объемная задача, чем использование утилиты с хорошо продуманным интерфейсам. Впрочем это верно и для командлетов. Вывод напрашивается сам собой: PowerShell позволяет нам использовать всю мощь .NET Framework, но иногда мощь языка программирования нам лишняя: если есть удобная утилита, то в большинстве случаев ее можно использовать в PowerShell легко, просто и удобно получая компактный и быстрый скрипт для решения задачи.

You have no rights to post comments

Яндекс.Метрика