Contents

Iniciar RDP o SSH sobre una VM desde PowerCLI

Si como yo os pasáis el día conectados a una infraestructura VMware vSphere haciendo conexiones remotas a diferentes máquinas virtuales sabréis que utilizar la consola integrada de VMware no es la mejor de las opciones. Como sustitución acostumbro a utilizar RDP para las máquinas virtuales Windows y SSH para las GNU/Linux, el gran problema para mi siempre ha sido cómo gestionar toda esa cantidad de conexiones remotas.

Si bien existe software para gestionar dichas conexiones siempre he encontrado que es una solución demasiado manual y que escala muy mal conforme añadimos máquinas a la ecuación. Puesto que me tiro todo el día con una consola de PowerShell abierta y conectado a mi infraestructura me decidí a crear un par de funciones muy sencillitas con las que hacer dicha gestión desde PowerShell de una forma muy fácil y dinámica.

Averiguar la IP enrutable de una VM

La primera problemática para crear una solución de este tipo es obtener la IP correcta sobre la que queremos conectarnos. Es posible que esto no aplique a todo el mundo, pero cuando una VM tiene más de una IP debemos obtener la que esté en el mismo rango que su gateway para asegurarnos de que seremos capaces de enrutar hacia ella en el caso de estar en una VLAN distinta.

Para conseguir la IP correcta de la máquina virtual utilizo esta función:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Function Get-VMIP {
    # Devuelve la IP principal de la VM (Determinado por la primera IP de la misma subred del GW)
    Param(
        [Parameter(
            Position = 0,
            ValueFromPipeline=$true,
            Mandatory=$true
        )]
        [string]$Name
        )
    $ips = (Get-VM $Name).ExtensionData.Guest.Net.IpAddress

    # Si solo existe una IP la devolvemos como principal
    if ($ips.Count -eq 1) {
        Return $ips
    }
    # Si existe más de una IP devolvemos como principal la que está en la misma subred que el GW (solo aplica a las /24)
    elseif ($ips.Count -gt 1) {
        # Obtenemos el gateway para comparar
        $gateway = (Get-VM $Name).ExtensionData.Guest.Ipstack.IpRouteConfig.IpRoute.Gateway.IpAddress
        # Recorremos las IPs
        foreach ($ip in $ips) {
            if ($gateway[0].Split('.')[2] -eq $ip.Split('.')[2]) {
                Return $ip
            }
        }
    }
    # Si no existen IP's devolvemos null
    else {
        Return $null
    }
}

Hay que teneren cuenta que esta solución sólo funciona con redes /24, que es con las que trabajo yo en mi infraestructura, pero se podría adaptar para funcionar con cualquier máscara.

Como siempre vamos a ver qué hace cada parte del código:

  • Líneas 3 a 10: Definimos el parámetro $Name que corresponderá al nombre de la VM de la que obtendremos la IP.
  • $ips = (Get-VM $Name).ExtensionData.Guest.Net.IpAddress: Obtenemos todas las IPs de la máquina virtual.
  • Líneas 14 a 16: Si sólo existe una IP la devolvemos.
  • Líneas 18 a 27: Si existe más de una IP sacamos el gateway y comparamos todas las IPs con éste hasta encontrar la que pertenezca a la misma subred. Una vez encontrada devolvemos la IP.
  • Líneas 29 a 31: Si no existen IPs devolvemos $null.

Con nuestra nueva función cargada ya podríamos ejecutar Get-VMIP para obtener la IP de una máquina virtual:

/wp-content/uploads/2018/11/Iniciar-RDP-con-PowerShell.png
Iniciar RDP con PowerCLI

Iniciar RDP o SSH sobre una VM

Ahora que ya tenemos creada nuestra función Get-VMIP podemos seguir con la función que realmente utilizaremos: Start-VMRc. Para la conexión SSH Start-VMRC se apoyará en Putty, por lo que deberemos descargarlo y ubicarlo en algún lugar de nuestro path, como C:\Windows\System32.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Start-VMRc {
    # Inicia una conexión remota RDP o SSH en función del sistema operativo
    param  
    (  
        [Parameter(
            Position = 0,
            ValueFromPipeline=$true,
            Mandatory=$true
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )
    # Determinamos la IP enrutable de la máquina
    $ip = Get-VMIP -Name $Name
    # Si es una máquina Windows iniciamos RDP
    if ((Get-VM -Name $Name).GuestId -like '*windows*'){
        mstsc /v:$ip
    }
    # Si es una máquina linux iniciamos Putty
    else {
        putty $ip
    }
}

Vamos a desglosar la función:

  • Líneas 3 a 12: Definimos el parámetro $Name que corresponderá al nombre de la VM a la que nos conectaremos remotamente.
  • $ip = Get-VMIP -Name $Name: Invocamos Get-VMIP para obtener la IP de la VM.
  • Líneas 16 a 18: Determinamos si es una máquina Windows y, en caso de serlo, iniciamos un RDP a la IP de la misma.
  • Líneas 20 a 22: De no ser una máquina Windows iniciamos SSH mediante Putty a su IP.

Si tenemos las dos funciones cargadas ya podemos ejecutar Start-VMRC para iniciar RDP contra nuestro servidor con:

1
Start-VMRC 'Sobrebits VM'

Conclusión

Una vez tengamos creadas las dos funciones podemos añadirlas a nuestro perfil tal y como vimos en la entrada ‘Cómo personalizar nuestro perfil de PowerShell’.

Yo particularmente utilizo a diario estas dos funciones y os puedo asegurar que si os acostumbráis a ellas os pueden ahorrar una cantidad tremenda de tiempo.

¡Espero que os sea útil!