Каков наилучший способ автоматизации безопасного FTP в PowerShell? - PullRequest
26 голосов
/ 05 ноября 2008

Я бы хотел автоматизировать загрузку по FTP файла резервной копии базы данных с помощью PowerShell. Имя файла включает в себя дату, поэтому я не могу просто запускать один и тот же сценарий FTP каждый день. Есть ли чистый способ сделать это встроенным в PowerShell или с помощью .Net framework?

ОБНОВЛЕНИЕ Я забыл упомянуть, что это безопасный сеанс FTP.

Ответы [ 8 ]

24 голосов
/ 06 ноября 2008

После некоторых экспериментов я придумал этот способ автоматизации безопасной загрузки по FTP в PowerShell. Этот сценарий запускается с публичного тестового FTP-сервера , администрируемого Chilkat Software. Таким образом, вы можете скопировать и вставить этот код, и он будет работать без изменений.

$sourceuri = "ftp://ftp.secureftp-test.com/hamlet.zip"
$targetpath = "C:\hamlet.zip"
$username = "test"
$password = "test"

# Create a FTPWebRequest object to handle the connection to the ftp server
$ftprequest = [System.Net.FtpWebRequest]::create($sourceuri)

# set the request's network credentials for an authenticated connection
$ftprequest.Credentials =
    New-Object System.Net.NetworkCredential($username,$password)

$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$ftprequest.UseBinary = $true
$ftprequest.KeepAlive = $false

# send the ftp request to the server
$ftpresponse = $ftprequest.GetResponse()

# get a download stream from the server response
$responsestream = $ftpresponse.GetResponseStream()

# create the target file on the local system and the download buffer
$targetfile = New-Object IO.FileStream ($targetpath,[IO.FileMode]::Create)
[byte[]]$readbuffer = New-Object byte[] 1024

# loop through the download stream and send the data to the target file
do{
    $readlength = $responsestream.Read($readbuffer,0,1024)
    $targetfile.Write($readbuffer,0,$readlength)
}
while ($readlength -ne 0)

$targetfile.close()

Я нашел много полезной информации по этим ссылкам

Если вы хотите использовать SSL-соединение, вам нужно добавить строку

$ftprequest.EnableSsl = $true

к сценарию перед вызовом GetResponse (). Иногда вам может потребоваться иметь дело с сертификатом безопасности сервера, срок действия которого истек (как, к сожалению, у меня). В репозитории кодов PowerShell есть страница, на которой есть фрагмент кода для этого. Первые 28 строк являются наиболее актуальными для загрузки файла.

7 голосов
/ 05 ноября 2008

взято с здесь

$source = "ftp://ftp.microsoft.com/ResKit/win2000/dureg.zip"
$target = "c:\temp\dureg.zip"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($source, $target)

У меня работает

4 голосов
/ 05 ноября 2008

Что касается PowerShell, пакет / n Software NetCmdlets включает в себя командлеты FTP (включая поддержку обоих типов защищенного FTP), которые вы могли бы довольно легко использовать для этого.

2 голосов
/ 07 апреля 2011

JAMS Job Scheduler предлагает несколько командлетов, которые упростят эту задачу. Он имеет различные командлеты FTP для безопасных сеансов, а также командлеты дат для преобразования натуральных дат в объекты дат .Net, такие как «Последний день месяца»:

Командлеты планировщика заданий JAMS

1 голос
/ 16 мая 2012

Примерно так может работать:

$bkdir = "E:\BackupsPWS" #backups location directory
$7Zip = 'C:\"Program Files"\7-Zip\7z.exe' #compression utility
$files_to_transfer = New-Object System.Collections.ArrayList #list of zipped files to be   transferred over FTP
$ftp_uri="myftpserver"
$user="myftpusername"
$pass="myftppassword"

#find .bak files not zipped yet, zip them, add them to the list to be transferrd
get-childitem -path $bkdir | Sort-Object length |
where { $_.extension -match ".(bak)" -and
-not (test-path ($_.fullname -replace "(bak)", "7z")) } |
foreach {
$zipfilename = ($_.fullname -replace "bak", "7z")
Invoke-Expression "$7Zip a $zipfilename $($_.FullName)"
$files_to_transfer.Add($zipfilename)
}

#find .bak files, if they've been zipped, delete the .bak file
get-childitem -path $bkdir |
where { $_.extension -match ".(bak)" -and
(test-path ($_.fullname -replace "(bak)", "7z")) } |
foreach { del $_.fullname }

#transfer each zipped file over FTP
foreach ($file in $files_to_transfer)
{
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) # FTP credentials
$ftp_urix = $ftp_uri + "/" + $file.Substring($bkdir.Length + 1) # ftp address where to transfer   the file
$uri=[system.URI] $ftp_urix
$webclient.UploadFile($uri, $file) #transfer the file
}

Проверьте это: Powershell: сжатие резервных копий и передача по FTP

1 голос
/ 05 ноября 2008

Это не так просто, как хотелось бы. Есть три варианта, которые я знаю.

1) .Net. Вы можете использовать .Net Framework для этого в PS, но это включает необработанные манипуляции с сокетами, которые я не хотел бы делать в сценарии. Если бы я шел по этому пути, то я бы обернул весь мусор ftp в DLL на C #, а затем использовал бы эту DLL из powershell.

2) Управление файлом - если вы знаете шаблон имени файла, который вам нужно получать каждый день, вы можете просто открыть свой ftp-скрипт с помощью PS и изменить имя файла в этом скрипте. Затем запустите скрипт.

3) Передача текста на FTP - последний вариант - использовать powershell для передачи информации в и из сеанса FTP. Смотри здесь .

0 голосов
/ 05 ноября 2008

$ realdate = (Get-Date) .ToString ("yyyyMMdd")

$ path = "D: \ samplefolderstructure \ filename" + $ realdate + ".msi"

ftps -f $ path -s: D: \ FTP.txt

ftp.txt - это способ хранения всей информации о нашем соединении с ftp-сервером. ftps - это клиент, который мы используем, очевидно, поэтому, возможно, придется изменить несколько вещей. Но это должно помочь вам понять идею.

0 голосов
/ 05 ноября 2008

Я успешно использовал библиотеку Indy Project .NET для работы с FTP. И ... тьфу, похоже, размещенная сборка .NET больше недоступна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...