,

Script de PowerShell para subir ficheros automáticamente a un FTP remoto

·

Script de PowerShell para subir ficheros automáticamente a un FTP remoto

Hace poco tuvimos una necesidad: transferir cada pocos minutos todos los ficheros XML de una carpeta a un FTP remoto. Hay muchas formas de hacerlo, y algunas pasan por software de pago. En nuestro caso eran ficheros XML generados por un servidor SAP en un entorno Windows, así que optamos por un script de PowerShell que podemos ejecutar con el Programador de tareas de Windows.

El script usa las librerías .NET de WinSCP, así que primero hay que instalar este programa, ligero y gratuito. Lo encontraréis aquí: winscp.net

Cómo funciona el script

  1. Sube los ficheros de la carpeta local al servidor FTP remoto.
  2. Cuando un fichero se ha subido correctamente, lo mueve a una carpeta de ficheros enviados.
  3. Si el fichero ya existe en el FTP o en la carpeta de enviados, lo sobrescribe.
  4. Si hay un error, lo escribe en el registro.
  5. Todos los movimientos quedan registrados con fecha y hora.

Este es el script, que podéis guardar en un fichero .ps1, por ejemplo upload_ftp.ps1:


#Preparamos el registro
$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
#Ubicación del fichero de registro
Start-Transcript -path C:\ftpscript\log\log.txt -append


try
	{
	# Cargamos la librería .NET de WinSCP
	[Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\WinSCP\WinSCPnet.dll") | Out-Null

	# Datos del FTP
	$sessionOptions = New-Object WinSCP.SessionOptions
	$sessionOptions.Protocol = [WinSCP.Protocol]::ftp
	$sessionOptions.HostName = "ftp.remotelocation.com"
	$sessionOptions.UserName = "ftpusername"
	$sessionOptions.Password = "ftpmpassword"
	# $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"

	$session = New-Object WinSCP.Session


	try
		{
			# Conexión
			$session.Open($sessionOptions)

			$localPath = "C:\ftpscript\upload\*.xml"
			$remotePath = "/"
			$backupPath = "C:\ftpscript\uploaded"
			$aData = Get-Date

			# Subimos los ficheros y recogemos el resultado
			$transferOptions = New-Object WinSCP.TransferOptions
			$transferResult = $session.PutFiles($localPath, $remotePath)

			# Recorremos los ficheros
			foreach ($transfer in $transferResult.Transfers)
				{
					# ¿Correcto o error?
					if ($transfer.Error -eq $Null)
						{
							Write-Host ("${aData} - El fichero {0} se ha subido y se ha movido a la carpeta de enviados" -f
							$transfer.FileName)
							# Si ha ido bien, lo movemos a la carpeta de enviados
							Move-Item $transfer.FileName $backupPath -force
						}
					else
						{
							Write-Host ("${aData} - Error en el fichero {0}: {1}" -f
							$transfer.FileName, $transfer.Error.Message)
						}
				}
			}

			finally
			{
				# Desconectamos y limpiamos
				$session.Dispose()
			}

			exit 0
	}

catch [Exception]
	{
		Write-Host $_.Exception.Message
		exit 1
	}

# Cerramos el registro
Stop-Transcript

Consejo: si el servidor lo permite, usad SFTP o FTPS en lugar de FTP, que envía la contraseña sin cifrar. Con WinSCP solo hay que cambiar el protocolo e indicar la huella de la clave del servidor.

Traducción hecha con ayuda de IA a partir del artículo original.