2008-11-05 14 views
26

Me gustaría automatizar la descarga FTP de un archivo de copia de seguridad de base de datos utilizando PowerShell. El nombre del archivo incluye la fecha, por lo que no puedo ejecutar el mismo script FTP todos los días. ¿Hay alguna manera clara de hacerlo integrado en PowerShell o utilizando .Net framework?¿Cuál es la mejor manera de automatizar FTP seguro en PowerShell?

ACTUALIZACIÓN Me olvidé de mencionar que esto es a través de una sesión de FTP segura.

Respuesta

1

Esto no es tan simple como desearía que fuera. Hay tres opciones que conozco.

1) .Net - Puede usar el .Net framework para hacer esto en PS, pero implica manipulación de socket sin procesar que no me gustaría hacer en un script. Si estuviera yendo por esta ruta, terminaría toda la basura de ftp en una DLL en C# y luego usaría esa DLL de powershell.

2) Manipulación de un archivo: si conoce el patrón del nombre del archivo que necesita obtener cada día, entonces simplemente podría abrir su script ftp con PS y cambiar el nombre del archivo en el script. Luego ejecuta el script.

3) Transmitir texto a FTP: la última opción es usar powershell para canalizar información hacia y desde su sesión de FTP. Ver here.

7

Tomado de here

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

Obras para mí

+0

eso es una cuarta opción válida que debería haber pensado. Si va a saber el nombre del archivo con anticipación, esta es ciertamente una buena solución y debe aceptarla como la respuesta. – EBGreen

0

he utilizado con éxito la biblioteca Indy Proyecto .NET para hacer FTP. Y ... ugh, parece que la compilación .NET alojada ya no está disponible.

0

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

$ path = "D: \ samplefolderstructure \ nombre de archivo" + $ realdate + ".msi"

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

ftp.txt es la forma en que guardamos toda nuestra información de conexión al servidor ftp. ftps es el cliente que usamos obviamente, por lo que podría tener que cambiar algunas cosas. Pero, esto debería ayudarte a ge la idea.

4

En lo que respecta a PowerShell, el paquete/n Software NetCmdlets incluye cmdlets FTP (incluido el soporte para ambos tipos de FTP seguro) que podría usar con bastante facilidad para esto.

24

Después de un poco de experimentación, se me ocurrió esta manera de automatizar una descarga de FTP segura en PowerShell. Este script se ejecuta en el public test FTP server administrado por Chilkat Software. Entonces puede copiar y pegar este código y se ejecutará sin modificaciones.

$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() 

He encontrado una gran cantidad de información útil en estos enlaces

Si desea utilizar una conexión SSL es necesario agregar la línea

$ftprequest.EnableSsl = $true 

al script antes de llamar a GetResponse(). A veces puede necesitar lidiar con un certificado de seguridad del servidor caducado (como desafortunadamente lo hago). Hay una página en el PowerShell Code Repository que tiene un fragmento de código para hacer eso. Las primeras 28 líneas son las más relevantes para descargar un archivo.

+1

+1 para encontrar y publicar una solución de código sobre esto. Sin embargo, sería genial ver algunos comentarios en el código. Por seguridad, supongo que quiere decir que se proporciona un usuario/pase y no necesariamente SFTP. –

+0

@Scott - Gracias por su comentario. Agregué algunos comentarios al código que aclararán las cosas. También agregué algo de información sobre la conexión a través de SSL. No había pensado en esto antes. –

+0

Código útil, pero no resuelve su problema de tratar con el nombre de archivo único –

1

El programador de trabajos JAMS ofrece algunos cmdlets que simplificarían esta tarea. Tiene una gran variedad de cmdlets FTP para sesiones seguras, así como cmdlets fecha para la conversión de fechas naturales en los objetos de fecha .Net como "Último día del mes":

JAMS Job Scheduler Cmdlets

1

Algo como esto podría funcionar:

$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 
} 

Comprobar esto: Powershell: compress backups and FTP transfer

Cuestiones relacionadas