Descubriendo módulos: Copiar archivos de Linux con PowerShell

Hace unos días me encontré con la necesidad de añadir a uno de mis scripts de automatización la capacidad de copiar archivos de Linux con PowerShell y descubrí un módulo perfecto para ello. Es por ello que en la entrada de hoy retomamos la sección ‘Descubriendo módulos’ (aquí podéis ver la entrada anterior) en la que cacharrearemos con el módulo WinSCP de PowerShell y copiaremos archivos desde una máquina Windows a una GNU/Linux y viceversa.

¿Qué es WinSCP y SCP?

No pretendo descubrir a nadie qué es WinSCP, pero por si hubiera algún rezagado no está de más escribir un par de líneas al respecto. WinSCP es una aplicación libre (licenciada con GPL) para sistemas operativos Microsoft Windows que nos permite interactuar a nivel de archivos con otros sistemas mediante SCP, FTP, SFTP o WebDAV.

SCP (Secure Copy Protocol) es un protocolo que nos permite realizar transferencias entre dos máquinas de forma segura basándose en SSH para tal fin.

SCP sobre Windows con PowerShell

Aprovechando que casi todas las máquinas GNU/Linux incorporan SSH, SCP se convierte en una especie de estándar a la hora de copiar archivos entre máquinas con dicho sistema. El problema viene si queremos copiar archivos de Linux a Windows, puesto que las máquinas Windows no incorporan un cliente SCP por defecto, y aquí es donde WinSCP se ha hecho un hueco.

Si bien WinSCP incorpora opciones de línea de comandos, no existen cmdlets propios de PowerShell. Por suerte en nuestra querida PowerShell Gallery podemos encontrar un módulo de WinSCP para PowerShell listo para descargar:

Install-Module -Scope CurrentUser -Name WinSCP

Como siempre después de instalar un nuevo módulo en nuestra máquina podemos consultar las funciones instaladas por el mismo:

Copiar archivos de Linux con PowerShell

Conectando a una máquina Linux por SCP con PowerShell

Ahora que ya tenemos claro que tenemos instalado el módulo de WinSCP para PowerShell y que tenemos claro qué son SCP y WinSCP podemos ponernos manos a la obra.

Antes de realizar cualquier operación necesitaremos crear una sesión contra la máquina de destino mediante New-WinSCPItem. Para ello necesitaremos un objeto PSCredential que, o bien lo solicitamos con Get-Credential para realizar una sesión interactiva, o bien podemos guardarlo en un archivo XML como vimos en la entrada “Cómo gestionar las credenciales de un script de PowerShell“.

# Pedimos credenciales
$Creds = Get-Credential
# Configuramos los parámetros de la sesión
$WinScpSessionOption = New-WinSCPSessionOption -Credential $Creds -GiveUpSecurityAndAcceptAnySshHostKey -HostName 192.168.168.168 -Protocol Scp
# Establecemos la conexión
$WinScpSession = New-WinSCPSession -SessionOption $WinScpSessionOption

Vamos a explicar qué hemos hecho:

  • $Creds = Get-Credential: Pedimos credenciales de conexión a la máquina destino.
  • $WinScpSessionOption = New-WinSCPSessionOption: Creamos una nueva definición de opciones de WinSCP y la guardamos en la variable $WinScpSessionOption para reutilizarla en futuros comandos.
    • -Credential $Creds: Utilizamos las credenciales obtenidas en la línea anterior.
    • -GiveUpSecurityAndAcceptAnySshHostKey: Aceptamos cualquier clave de SSH.
    • -HostName 192.168.168.168: Establecemos el host de destino.
    • -Protocol Scp: Establecemos el protocolo a utilizar.
  • $WinScpSession = New-WinSCPSession -SessionOption $WinScpSessionOption: Utilizamos la variable creada en la línea anterior para generar una nueva sesión y guardarla en la variable $WinScpSession que utilizaremos durante la ejecución de nuestros comandos.

Copiar archivos de Linux con PowerShell

En este punto ya tenemos nuestra sesión en la variable $WinScpSession, así que ya podemos ponernos a copiar archivos en ambas direcciones.

Empezamos copiando archivos de Linux a Windows con PowerShell mediante Receive-WinSCPItem:

Receive-WinSCPItem -WinSCPSession $WinScpSession -RemotePath "/tmp/sobrebits.txt" -LocalPath 'C:\Windows\Temp'

Una explicación rápida:

  • WinSCPSession: Aquí introducimos la sesión creada en el paso anterior.
  • RemotePath: Ruta completa del archivo a copiar.
  • LocalPath: Ruta donde copiaremos el archivo.

Si en cambio queremos copiar archivos de Windows a Linux con PowerShell deberemos hacerlo con Send-WinSCPItem:

Send-WinSCPItem -WinSCPSession $WinScpSession -LocalPath 'C:\Windows\Temp\sobrebits.txt' -RemotePath "/tmp"

Ningún misterio aquí, mismas opciones que en la línea anterior pero cambia el sentido en el que copiamos el archivo.

Otras opciones interesantes de WinSCP para PowerShell

Si bien solo hemos visto cuatro de las funciones disponibles en este módulo existen un total de 23 funciones en el mismo (a la fecha de escribir este post), que por razones obvias no vamos a cubrir. No obstante os voy a enumerar los que me han parecido más interesantes:

  • Remove-WinSCPSession: Con el que desconectar sesiones existentes.
  • Move-WinSCPItem: Para mover o renombrar un archivo del sistema remoto.
  • Copy-WinSCPItem: Para copiar un archivo del sistema remoto.
  • Test-WinSCPPath: Con el que comprobar si existe un archivo o carpeta remoto.
  • Sync-WinSCPPath: Para sincronizar una carpeta local con otra remota.

Conclusión

Con el módulo de WinSCP para PowerShell podemos ampliar la gama de funcionalidad de nuestros scripts para que no solo interactuen con sistemas de ficheros locales, sino que también lo puedan hacer contra sistemas remotos GNU/Linux o incluso contra datastores de VMware vSphere (si el nodo en cuestión dispone de SSH habilitado).

Además, no olvidéis que más allá de SCP podéis conectaros a sistemas remotos mediante SFTP, FTP y WebDAV utilizando el mismo set de funciones.

¡Espero que os sirva!

One Response

  1. Gorka noviembre 1, 2018

Deja un comentario