PSFTP – UploadFile

Kolejnym z ważniejszych elementów zarządzania kontem ftp jest możliwość wysłania pliku do lokalizacji zdalnej. Jak w poprzednich obu przypadkach również wykorzystujemy klasę FtpWebRequest.

Jak poprzednio konfigurujemy połączenie do lokalizacji ftp.

$RequestUri = "ftp://myserverftp.pl/myfolder/file5.zip"
$LocalPath = "c:\file5.zip"
[System.Net.FtpWebRequest]$Request = [System.Net.WebRequest]::Create($RequestUri)
$Request.Credentials = Get-Credential
$Request.EnableSsl = $true
$Request.KeepAlive = $true
$Request.UseBinary = $true
$Request.UsePassive = $true
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Sprawdzamy czy plik już istnieje w danej lokalizacji I jeśli tak to sczytujemy jego wielkość. Posłuży nam to do umożliwienia kontynuowania wysyłania pliku w razie nieprzewidzianej awarii.

Try
{
  [System.Net.FtpWebRequest]$RequestTmp = [System.Net.WebRequest]::Create($RequestUri)
  $RequestTmp.Credentials = $Request.Credentials
  $RequestTmp.EnableSsl = $Request.EnableSsl
  $RequestTmp.KeepAlive = $Request.KeepAlive
  $RequestTmp.UseBinary = $Request.UseBinary
  $RequestTmp.UsePassive = $Request.UsePassive
  $RequestTmp.Method = [System.Net.WebRequestMethods+FTP]::GetFileSize
  $ResponseTmp = $RequestTmp.GetResponse()
  $FileSize = $ResponseTmp.ContentLength
  $ResponseTmp.Close()
}
Catch
{
  $FileSize = 0
}

Jeżeli plik już istnieje, tzn. jego wielkość jest większa od 0 to pytamy się co zrobić. Czy kontynuujemy wysyłanie czy może będziemy wysyłać plik od początku.

if($FileSize)
{
  $Title = "A File name already exists in this location."
  $Message = "What do you want to do?"
  $Overwrite = New-Object System.Management.Automation.Host.ChoiceDescription "&Overwrite"
  $Cancel = New-Object System.Management.Automation.Host.ChoiceDescription "&Cancel"
  $Resume = New-Object System.Management.Automation.Host.ChoiceDescription "&Resume"
  $Options = [System.Management.Automation.Host.ChoiceDescription[]]($Cancel, $Overwrite, $Resume)
  $SendFlag = $host.ui.PromptForChoice($Title, $Message, $Options, 2)
  $Request.Method = [System.Net.WebRequestMethods+FTP]::AppendFile
}
else
{
  $SendFlag = 1
  $Request.Method = [System.Net.WebRequestMethods+FTP]::UploadFile
}

Przejdźmy teraz do serca skryptu, czyli otwieramy lokalny plik do odczytu i wysyłamy zapytanie do serwera ftp.

$File = [IO.File]::OpenRead($LocalPath)
$Response = $Request.GetRequestStream()

Jak przy odbieraniu danych tak i przy wysyłaniu tworzymy bufor I ustawiamy wielkość wysyłanej paczki danych.

$BufferSize = 20KB
[Byte[]]$Buffer = New-Object Byte[] $BufferSize

Ustalamy dane do celów statystycznych.

$ReadedData = 0
$AllReadedData = 0
$TotalData = (Get-Item $LocalPath).Length

I W zależności od wybranego trybu wysyłania danych ustawiamy znacznik na pliku lokalnym na wielkości pliku znajdującego się na serwerze ftp, lub rozpoczynamy cały proces wysyłania od początku.

if($SendFlag -eq 2)
{
  $SeekOrigin = [System.IO.SeekOrigin]::Begin
  $File.Seek($FileSize,$SeekOrigin) | Out-Null
  $AllReadedData = $FileSize
}

Do {
  $ReadedData = $File.Read($Buffer, 0, $Buffer.Length)
  $AllReadedData += $ReadedData
  $Response.Write($Buffer, 0, $ReadedData);
  Write-Progress -Activity "Upload File: $RequestUri" -Status "Uploading:" -Percentcomplete ([int]($AllReadedData/$TotalData * 100))
} While($ReadedData -gt 0)

Na zakończenie zamykamy plik lokalny oraz zamykamy połączenie.

$File.Close()
$Response.Close()

Całość wygląda następująco:

$RequestUri = "ftp://myserverftp.pl/myfolder/file5.zip"
$LocalPath = "c:\file5.zip"
[System.Net.FtpWebRequest]$Request = [System.Net.WebRequest]::Create($RequestUri)
$Request.Credentials = Get-Credential
$Request.EnableSsl = $true
$Request.KeepAlive = $true
$Request.UseBinary = $true
$Request.UsePassive = $true
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Try
{
  [System.Net.FtpWebRequest]$RequestTmp = [System.Net.WebRequest]::Create($RequestUri)
  $RequestTmp.Credentials = $Request.Credentials
  $RequestTmp.EnableSsl = $Request.EnableSsl
  $RequestTmp.KeepAlive = $Request.KeepAlive
  $RequestTmp.UseBinary = $Request.UseBinary
  $RequestTmp.UsePassive = $Request.UsePassive
  $RequestTmp.Method = [System.Net.WebRequestMethods+FTP]::GetFileSize
  $ResponseTmp = $RequestTmp.GetResponse()
  $FileSize = $ResponseTmp.ContentLength
  $ResponseTmp.Close()
}
Catch
{
  $FileSize = 0
}

if($FileSize)
{
  $Title = "A File name already exists in this location."
  $Message = "What do you want to do?"
  $Overwrite = New-Object System.Management.Automation.Host.ChoiceDescription "&Overwrite"
  $Cancel = New-Object System.Management.Automation.Host.ChoiceDescription "&Cancel"
  $Resume = New-Object System.Management.Automation.Host.ChoiceDescription "&Resume"
  $Options = [System.Management.Automation.Host.ChoiceDescription[]]($Cancel, $Overwrite, $Resume)
  $SendFlag = $host.ui.PromptForChoice($Title, $Message, $Options, 2)
  $Request.Method = [System.Net.WebRequestMethods+FTP]::AppendFile
}
else
{
  $SendFlag = 1
  $Request.Method = [System.Net.WebRequestMethods+FTP]::UploadFile
}

if($SendFlag)
{
  $File = [IO.File]::OpenRead($LocalPath)
  $Response = $Request.GetRequestStream();
  $BufferSize = 20KB
  [Byte[]]$Buffer = New-Object Byte[] $BufferSize

  $ReadedData = 0
  $AllReadedData = 0
  $TotalData = (Get-Item $LocalPath).Length

  if($SendFlag -eq 2)
  {
    $SeekOrigin = [System.IO.SeekOrigin]::Begin
    $File.Seek($FileSize,$SeekOrigin) | Out-Null
    $AllReadedData = $FileSize
  }

  Do {
    $ReadedData = $File.Read($Buffer, 0, $Buffer.Length)
    $AllReadedData += $ReadedData
    $Response.Write($Buffer, 0, $ReadedData);
    Write-Progress -Activity "Upload File: $RequestUri" -Status "Uploading:" -Percentcomplete ([int]($AllReadedData/$TotalData * 100))
  } While($ReadedData -gt 0)

  $File.Close()
  $Response.Close()
}

Źródła:
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx
http://msdn.microsoft.com/en-us/library/system.net.webrequestmethods.ftp.aspx
http://gallery.technet.microsoft.com/scriptcenter/PowerShell-FTP-Client-db6fe0cb

Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s