fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
2 minut

FTPS w Powershell


23.07.2012

Przy okazji prac nad http://msmvp.pl dość regularnie musiałem przerzucać bazkę SQL CE z jednego miejsca w drugie (z aplikacji do zbierania danych w "publiczny" portal), przez FTP. A nawet FTPS. Z początku robiłem to ręcznie, ale wiadomo: gdy jakieś czynności zaczynają nużyć to warto je zautomatyzować.

W pracy jestem czasami wystawiony na Powershell, sam także w nim momentami popisuję, i muszę przyznać, że moja początkowa antypatia do tego narzędzia mija. Bez zastanowienia więc wybrałem właśnie PS jako środek do w pełni zautomatyzowanego przerzucania pliku z jednej aplikacji do drugiej.

Podstawowa komunikacja przez FTP jest w .NET dość wygodnie zaimplementowana w klasie FtpWebRequest i sprawnie poszło mi zrobienie tego co trzeba po gołym FTP. Jednak FTP tylko tylko FTPS bez S, jak Psikuta, i to S musiałem dodać. Problem pojawił się, gdy chciałem zaakceptować certyfikat serwera, który domyślnie był odrzucany. Poniżej funkcja tworząca żądanie FTPS:

function prepareRequest{
  param([string]$uri)
  $ftprequest = [System.Net.FtpWebRequest]::create($uri)
  $ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)
  $ftprequest.EnableSsl = $true
  $ftprequest.UseBinary = $true
  $ftprequest.KeepAlive = $false
  [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
  return $ftprequest
}

Kluczem była odpowiednia konfiguracja ServerCertificateValidationCallback. W C# robiłem to wielokrotnie, ale w Powershell z niezrozumiałych względów jakoś… utknąłem:).

Wykorzystanie funkcji do ściągnięcia pliku:

$ftprequest = prepareRequest($sourceuri);
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$ftpresponse = $ftprequest.GetResponse()
$responsestream = $ftpresponse.GetResponseStream()
$targetfile = New-Object IO.FileStream ($targetpath,[IO.FileMode]::Create)
[byte[]]$readbuffer = New-Object byte[] 1024
do{
    $readlength = $responsestream.Read($readbuffer,0,1024)
    $targetfile.Write($readbuffer,0,$readlength)
}
while ($readlength -ne 0)
$targetfile.close()

Pełen skrypt można obejrzeć na Githubie. Obok trzymam sobie *.bat z parametrami w postaci mojego loginu i hasła do Webio, jednak z oczywistych względów jest on dodany do .gitignore.

Comments are closed.

Kurs Gita

Zaawansowany frontend

Szkolenie z Testów

Szkolenie z baz danych

Książka

Zobacz również