Какой лучший способ автоматизировать защищенный FTP в PowerShell?
Я хотел бы автоматизировать FTP-загрузку файла резервной копии базы данных с помощью PowerShell. Имя файла включает дату, поэтому я не могу запускать один и тот же FTP script каждый день. Есть ли простой способ сделать это встроенным в PowerShell или с помощью .Net framework?
UPDATE Я забыл упомянуть, что это сеанс с защитой FTP.
Ответы
Ответ 1
После некоторых экспериментов я придумал этот способ для автоматизации безопасной загрузки FTP в PowerShell. Этот script запускает публичный тестовый 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 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
до script перед вызовом GetResponse(). Иногда вам может потребоваться справиться с сертификатом безопасности сервера, срок действия которого истек (например, я, к сожалению). В PowerShell Code Repository есть страница, в которой есть фрагмент кода для этого. Первые 28 строк наиболее важны для загрузки файла.
Ответ 2
Взято из здесь
$source = "ftp://ftp.microsoft.com/ResKit/win2000/dureg.zip"
$target = "c:\temp\dureg.zip"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($source, $target)
Работает для меня
Ответ 3
Что касается PowerShell, в /n Software NetCmdlets пакет включает в себя FTP-командлеты (включая поддержку как для защищенных типов FTP), которые вы могли бы используйте довольно легко для этого.
Ответ 4
Это не так просто, как хотелось бы. Есть три варианта, о которых я знаю.
1).Net. Вы можете использовать инфраструктуру .Net для этого в PS, но это связано с грубой обработкой сокета, которую я бы не хотел делать в script. Если бы я шел по этому маршруту, я бы завернул весь ftp-мусор в DLL на С#, а затем использовал эту DLL из powershell.
2) Манипулирование файлом. Если вам известен шаблон имени файла, который вам нужно получить каждый день, вы можете просто открыть свой ftp script с помощью PS и изменить имя файла в script. Затем запустите script.
3) Текст трубы на FTP. Последняя опция - использовать powershell для передачи информации в и из вашего FTP-сеанса. См. здесь.
Ответ 5
Планировщик заданий JAMS предлагает несколько командлетов, которые упростили бы эту задачу. Он имеет множество командлетов FTP для безопасных сеансов, а также командлетов даты для преобразования естественных дат в .Net объекты даты, такие как "Последний день месяца":
Командлеты планировщика заданий JAMS
Ответ 6
Что-то вроде этого может работать:
$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
Ответ 7
Я успешно использовал библиотеку Indy Project.NET для работы с FTP. И... тьфу, похоже, что размещенная .NET-сборка больше не доступна.
Ответ 8
$realdate = (Get-Date).ToString( "yyyyMMdd" )
$path = "D:\samplefolderstructure\filename" + $realdate + ".msi"
ftps -f $path -s: D:\FTP.txt
ftp.txt - это то, как мы сохраняем всю информацию о подключении на ftp-сервере. ftps - это клиент, которого мы используем, очевидно, поэтому, возможно, придется изменить несколько вещей. Но это должно помочь вам в идее.