Creación máquinas virtuales Hyper-V automáticamente

25 octubre 2016
Josep Ma Solanes 8

Esta entrada consiste en el proceso de creación máquinas virtuales sobre Hyper-V de forma automatizada, con una configuración concreta a partir de un disco duro, que se utiliza de plantilla, mediante un script de PowerShell. Normalmente, este proceso se hace con Microsoft System Center Virtual Machine Manager, sin embargo, en un entorno pequeño o si no disponemos de esta herramienta, esta puede ser una buena forma de semi-automatización.

 

Preparando una maqueta de Windows Server 2016 para la creación máquinas virtuales

Ei que también sirve para la versión Windows Server 2012 R2 y Windows 10. El proceso es el mismo.

Para empezar hay que disponer de un disco duro virtual que actúe como plantilla para las nuevas máquinas virtuales, algunos lo llamaréis maqueta, otros plancha, otros maestro, etc… la finalidad es la misma. Microsoft ha actualizado el sistema operativo de servidores, es una buena ocasión de crear las nuevas plantillas con Microsoft Windows Server 2016, ya sea con una versión de escritorio o core.

Naturalmente, la primera máquina virtual se tiene que montar a mano, (por lo menos en esta entrada), pero una vez la tenemos a nuestro gusto se puede dejar preparada para que actúe como plantilla.

 

¿Qué pasa con la licencia de Windows?

Al crear una plantilla no es adecuado hacerlo en un equipo con una licencia instalada, ya que al hacer la plantilla esta se pierde. Lo normal es hacerlo sin licencia o con una licencia de activación automática. Es decir, unas licencias preestablecidas que al introducirlas desencadena una serie de acciones en la máquina, por ejemplo, buscar en la red un equipo que asigne automáticamente las licencias (licencias KMS) o bien, si es una máquina virtual, que se active sola desde el anfitrión (AVMA).

Al crear la plantilla os recomiendo utilizar una clave AVMA (Automatic Virtual Machine Activation) o bien una KMS.

Licencias AVMA (Automatic Virtual Machine Activation)

Las máquinas se activan automáticamente mediante la licencia del anfitriónFunciona en entornos con Microsoft Hyper-V, tanto para licenciamiento OEM (adquirido con la máquina) como con licenciamiento de Volumen (licencias de contrato OPEN o SELECT).

El anfitrión tiene que ser un Windows Server 2012 R2 Datacenter o Windows Server 2016 Datacenter. ¡No sirve en licencias Standard!

Si la máquina anfitrión es un servidor Windows Server 2016 Datacenter, puede activar máquinas virtuales Windows Server 20162012 R2 con las ediciones Datacenter, Standard o Essentials.

Si la máquina anfitrión es un servidor Windows Server 2012 R2 Datacenter, puede activar máquinas virtuales Windows Server 2012 R2 con las ediciones Datacenter, Standard o Essentials. ¡No puede activar máquinas virtuales con Windows Server 2016!

 

Para que las máquinas virtuales se activen con este método, cumpliendo todo lo anterior, la clave de producto que deben tener instalada los equipos o máquinas virtuales para la activación automática corresponde a las siguientes tablas:

Las siguientes licencias NO activan el producto por sí solas, simplemente se informa al sistema operativo que debe hacer alguna cosa para encontrar la licencia definitiva, si no lo encuentra la máquina se queda sin activar.

Claves de activación AVMA para Windows Server 2012 R2 (sólo activa máquinas virtuales Windows Server 2012 R2)

Edición Clave a instalar
Datacenter Y4TGP-NPTV9-HTC2H-7MGQ3-DV4TW
Standard DBGBW-NPF86-BJVTX-K3WKJ-MTB6V
Essentials K2XGM-NMBT3-2R6Q8-WF2FK-P36R2

 

Claves de activación AVMA para Windows Server 2016 (activa máquinas virtuales Windows Server 2012 R2 y Windows Server 2016

Edición Clave a instalar
Datacenter TMJ3Y-NTRTM-FJYXT-T22BY-CWG3J
Standard C3RCX-M6NRP-6CXC9-TW2F2-4RHYD
Essentials B4YNW-62DX9-W8V6M-82649-MHBKQ

Si en el proceso de instalación no se ha utilizado una clave de este tipo, se puede añadir o cambiar mediante el siguiente comando de consola de sistema:

slmgr /ipk <clave_AVMA>

Por ejemplo, si tenemos una máquina virtual con Windows Server 2016 Standard, desde la consola de sistema ejecutaremos el siguiente comando para instalar la clave de producto:

slmgr /ipk C3RCX-M6NRP-6CXC9-TW2F2-4RHYD

 

Licencias KMS

Son para la activación de equipos mediante la red interna. Requieren de un servidor de licencias, que tiene instalada la clave KMS que se proporciona al comprar las licencias. Esta clave sólo se obtiene mediante un contrato de Volumen: OPEN, SELECT… No sirve para instalaciones con licencias OEM (licencias compradas con el equipo), en estos casos se tienen que instalar las licencias MAKasignada a cada equipo, ya sea físico o virtual.

A no ser que sean licencias de Windows Server Datacenter sobre Hyper-V que se puede utilizar el método anterior, el AVMA.

Claves de activación KMS para Windows Server 2016

Edición Clave a instalar
Datacenter CB7KF-BWN84-R7R2Y-793K2-8XDDG
Standard WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY
Essentials JCKRF-N37P4-C2D82-9YXRT-4M63B

 

Claves de activación KMS para Windows Server 2012 R2

Edición Clave a instalar
Datacenter W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9
Standard D2N9P-3P6X9-2R39C-7RTCD-MDVJX
Essentials KNC87-3J2TX-XB4WP-VCPJV-M4FWM

También pasa lo mismo que en el caso anterior, si la máquina virtual o, también en este caso, la física no se han instalado con esta clave de producto, se puede cambiar mediante el comando de consola de sistema:

slmgr /ipk <clave_KMS>

Ya sé que no es objeto de esta entrada, pero quizás también os interesa tener las claves KMS del sistema operativo cliente Microsoft Windows 10:

Claves de activación KMS para Windows 10

Edición Clave a instalar
Professional W269N-WFGWX-YVC9B-4J6C9-T83GX
Enterprise NPPR9-FWDCX-D2C8J-H872K-2YT43
Enterprise 2015 LTSB WNMTR-4C88C-JK8YV-HQ7T2-76DF9
Enterprise 2016 LTSB DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ
Education NW6C2-QMPVW-D7KKK-3GKT6-VCFB2

 

Archivo para la configuración desatendida

El siguiente punto es preparar el archivo de configuración desatendida (unattend.xml) para la inicialización del equipo una vez arranca por primera vez sin que pregunte demasiada cosa o nada.

Os dejo un archivo unattend.xml de ejemplo, que he creado con el entorno Microsoft Deployment Toolkit. La configuración es para tener el entorno en inglés, pero el teclado y configuración regional de las aplicaciones en español. La zona horaria corresponde a España. El nombre del equipo será automático empezando con el nombre de la empresa que se ha indicado en el archivo. Y, lo más importante, la contraseña del Administrador local se establece en P@ssw0rd

Copiar el archivo en la carpeta del sysprep por ejemplo. La ruta corresponde a: c:\Windows\System32\sysprep con el nombre unattend.xml.

Si lo tenemos todo a punto, cerramos la máquina (prepararla para hacer copias) para poder desplegar otras máquinas a partir de esta. Desde una consola de sistema con privilegios de administrador, ejecutar el siguiente comando:

c:\Windows\System32\sysprep\Sysprep /generalize /oobe /shutdown /unattend:c:\Windows\system32\sysprep\unattend.xml /mode:vm

El sistema prepara el equipo para ser copiado y lo deja parado. ¡Es el momento de hacer la copia del disco duro virtual! para otras máquinas virtuales.

Creació màquines virtuals. Procés Sysprep.
Creación máquinas virtuales. Proceso de cierre de la maqueta con Sysprep.

Una vez tenemos una nueva máquina con una copia del disco duro que hemos preparado, sólo hay que arrancarla. El sistema la ha personalizado sólo con lo que se ha especificado en el archivo unattend.xml.

Creació màquines virtuals. Inici de la nova màquina.
Creación máquinas virtuales. Inicio de la nueva máquina, el sistema operativo se personaliza.

Esperar un rato a que acabe, seguramente reiniciará alguna vez. No os preocupéis está siguiendo el guión. No os tiene que preguntar nada, el proceso es completamente automático con lo que le hemos pedido.

Creació màquines virtuals. Acabant de configurar els detalls de la personalització.
Creación máquinas virtuales. Acabando de configurar los detalles de la personalización del equipo de forma automática.

Finalizado todo el proceso, hacer Control + Alt + Supr para iniciar sesión. No hemos tenido que tocar nada y el sistema está listo para trabajar. Ojo, si habéis utilizado el archivo anterior unattend.xml, recordad que ha cambiado la contraseña de administrador local: P@ssw0rd

Creació màquines virtuals. La màquina ja s'ha iniciat sense cap intervenció externa.
Creación máquinas virtuales. La máquina ya se ha iniciado sin ninguna intervención externa. Todo a punto para empezar a trabajar.

 

Script PowerShell creación maquinas virtuales automáticamente

Tenemos la maqueta de la máquina virtual, o mejor dicho, su disco duro. Es el que está apagado y NO se ha encendido después de cerrar la maqueta. Lo reservamos en una carpeta aparte para hacer copias para las diferentes máquinas que tengamos que crear.

En este apartado empezamos a programar un poco con PowerShell para hacer lo siguiente:

  1. Crear una nueva máquina virtual con una configuración estándar.
  2. Conectar la máquina virtual a un switch virtual predefinido.
  3. Personalizar la configuración de la máquina virtual en cuanto a procesador, memoria, como se tiene que poner en marcha, como se tiene que parar, servicios de integración entre anfitrión y máquina virtual.
  4. Mover la definición de la máquina virtual a una carpeta con su nombre del qué colgarán todos los archivos que dependen de ella.
  5. Crear su disco duro C a partir del disco duro maestro que se ha creado en el proceso anterior.
  6. Asignar el disco duro C a la máquina virtual y establecerlo como único método de arranque de la misma.
  7. Poner en marcha la nueva máquina virtual.
  8. El proceso de instalación desatendida nos la dejará con la pantalla del Control + Alt + Supr. Lista para trabajar.

Ahora bien, no os quiero dejar sólo el script para ejecutarlo y ya está, no estaría haciendo bien el trabajo.

Se trata de enseñar a pescar, para que podáis seguir solos y no de daros todo masticado para que siempre dependais de alguien.

En el anfitrión de virtualización, abrir la consola de PowerShell en su entorno gráfico y con privilegios de administrador. En el menú de inicio téneis que buscar el Windows PowerShell ISEBotón derecho sobre el nombre y hacer clic en ejecutar como Administrador.

Obrir la consola gràfica de PowerShell amb privilegis d'administrador.
Abrir la consola gráfica de PowerShell con privilegios de administrador.

Asegurar que se visualiza la ventana para crear un script. En la pantalla anterior no está, hacer clic en la parte superior derecha la opción Script para visualizarla.

Creació màquines virtuals amb Hyper-V. En l'entorn gràfic accedir a la finestra de Script
Creación máquinas virtuales con Hyper-V. En el entorno gráfico acceder a la ventana de Script

Se debe escribir en la parte de arriba, para después poder ejecutar en la consola de PowerShell de la parte inferior de forma seguida. Lo haremos paso a paso, pero después lo juntaremos en dos funciones.

Establecemos los parámetros, digamos estándares, de las máquinas virtuales a crear. Nombre de la máquina virtual, ubicación del disco duro que se utilizará como plantilla (el que se ha creado en el paso anterior), nombre del switch virtual donde se conectará la máquina virtual, cantidad de memoria RAM estática que tendrá la máquina virtual y el número de virtual CPUs. Todo esto lo ponemos en variables al principio. Si tenemos la necesidad de cambiarlo, es más fácil hacerlo así que con código de por medio. Por lo tanto, se tienen que declarar variables. En PowerShell la declaración de variables se hace mediante el símbolo del dólar ($) delante del nombre. Los comentarios se marcan con el símbolo almohadilla (#) seguido del comentario. Estos no hace falta que se copien, sirven para entender el código.

$nombreVM = "srvPRUEBA"
$plantillaVHDX = "D:\VMs\Plantillas\Windows2016coreplantilla.vhdx"
$switch = "swExtern" #switch virtual donde conectar las máquinas virtuales.
$MemoriaRAM = 2048MB #memoria RAM de la máquina virtual.
$CPUs = 2 # número de procesadores virtuales

A continuación tenemos que jugar un poco con las variables anteriores para la reubicación de los archivos en el disco duro.

$CarpetaVM = "d:\VMs\" + $nombreVM  # La carpeta que contendrá las subcarpetas y archivos de la VM.
$CarpetaVHDX = $CarpetaVM + "\Virtual Hard Disks\" # La carpeta donde se copiará el disco duro virtual.
$UbicacionDisco = $CarpetaVHDX + $nombreVM + "_C.vhdx" # El nombre del disco duro virtual para la unidad C.

Ya tenemos todos los datos necesarios. El siguiente paso es hacer alguna cosa con ellos. Empezamos comprobando que el switch virtual existe. En caso que no exista, creamos uno del tipo Privado donde conectar la máquina virtual.

El comando if actúa como condicional (si pasa esto, haz esto otro). ¿El qué? pues se hace un listado de los switchs virtuales que tiene el anfitrión (Get-VMSwitch). De esta lista sólo se selecciona el que su nombre es el que se ha indicado en la variable $switch. Con el resultado, se hace un recuento (.count) de la cantidad de switch que puede haber. Si la lista contiene 1 elemento, bingo, el switch existe. Poniendo el símbolo de admiración al inicio (!), indica que se tiene que cumplir precisamente lo contrario, si la lista no es igual a 1, no tenemos switch. Por lo tanto, para no dar errores en la creación de máquinas virtuales, se crea uno de entorno privado. El comando write-host sirve para sacar alguna cosa por pantalla, en caso de crear el switch lo indica con el texto de color verde.

if (!(Get-VMSwitch | Where-Object -Property Name -eq $switch).count -eq 1)
{
   # El switch virtual no existe, se crea uno del tipo privado.
   New-VMSwitch -Name $switch -SwitchType Private
   write-host("No existe el switch parametrizado, se ha creado uno de privado llamado: " + $switch) -foregroundColor Green
}

Pasamos a crear la máquina virtual propiamente dicha (New-Vm), estableciendo los parámetros básicos necesarios. Nombre (-Name), memoria (-MemoryStartupBytes), switch (-SwitchName) y generación del hardware (Generation). Ya sabéis este último, 1 para máquinas Windows 2008 R2 atrás y 2 para máquinas Windows 2012 R2 delante. En lugar de los valores concretos, se utilizan las variables que se han declarado en la primera parte:

New-VM -Name $nombreVM -MemoryStartupBytes $MemoriaRAM -SwitchName $switch -Generation 2

Con la máquina virtual creada, la parte básica, como que ocupa poco espacio, es el momento de mover todos sus archivos a una ubicación única y controlada, que sinó después nos volvemos locos. Esto se hace con el Move-VMStorage. Indicando la máquina virtual (get-vm $nombreVM) y la carpeta de destino (-DestinationStoragePath). También podéis ver que se utilizan variables en lugar de nombres concretos.

Move-VMStorage -VM (get-vm $nombreVM) -DestinationStoragePath $CarpetaVM

Afinamos la configuración de la máquina virtual. Se define que la memoria sea estática (-StaticMemory) en lugar de dinámica, el número de CPUs (-ProcessorCount), que la máquina se ponga en marcha 10 segundos después de iniciar el anfitrión (-AutomaticStartAction Start y             -AutomaticStartDelay 10), que la máquina se pare ordenadamente al cerrar el anfitríón (-AutomaticStopAction ShutDown) y que no tenga habilitados los puntos de consistencia (snapshots) por defecto (-CheckpointType Disabled).

set-vm $nombreVM -StaticMemory -ProcessorCount $CPUs -AutomaticStartAction Start -AutomaticStartDelay 10 -AutomaticStopAction ShutDown -CheckpointType Disabled

También se deshabilita la sincronización de la hora desde el anfitrión a la máquina virtual. Si esto no lo tenéis bien configurado y hay una desincronización de más de 5 minutos, estáis fuera del Active Directory y ¡supone muchos problemas!

Disable-VMIntegrationService -VMName $nombreVM -name *time*

La máquina virtual ya está bien definida, falta el disco duro. Crear la carpeta para alojar los discos duros virtuales (new-item) dentro de la carpeta de la máquina virtual, copìar el disco duro que (copy-item) se ha maquetado y cambiarle el nombre (rename-item).

New-Item $CarpetaVHDX -type directory
Copy-item $plantillaVHDX -Destination $CarpetaVHDX
Rename-Item ($CarpetaVHDX + "Windows2016coreplantilla.vhdx") $UbicacionDisco

Añadir el nuevo disco duro a la máquina virtual (add-vmharddiskdrive) como disco duro SCSI (si la máquina es de generación 1 tiene que ser IDE) y configurarlo como método de inicio de la máquina virtual (set-vmfirmware). Si la máquina es de generación 1 tiene que ser set-vmbios:

Add-VMHardDiskDrive -VMName $nombreVM -Path $UbicacionDisco -ControllerType SCSI
Set-VMFirmware -VMName $NombreVM -BootOrder (Get-VMHardDiskDrive -VMName $nombrevm)

Ya está todo a punto, sólo queda poner en marcha la máquina virtual (start-vm) y que el proceso de maquetación acabe su trabajo. Nos podemos conectar a ella directamente (vmconnect):

start-vm (Get-VM $nombreVM)
vmconnect localhost $nombreVM

Con todo esto escrito en la parte superior, ya se puede poner en práctica haciendo clic en el botón del play o pulsando la tecla F5.

Creació màquines virtuals Hyper-V. Execució script PowerShell.

Esperar un rato. Dependiendo del tamaño de la plantilla tardará más o menos en copiarla. Es la parte más pesada de estos script.

Creació màquines virtuals Hyper-V. Executant l'script de PowerShell

Para acabar abriéndose una consola con la nueva máquina virtual acabando de personalizarse y quedarse con el Control + Alt + Supr lista para trabajar.

creacio-vm-hyperv-automaticament-009

 

La cosa no acaba aquí. Esto sólo crea una máquina virtual y ¿si quiero crear muchas de seguidas? ¿He de estar modificando este script cada vez? La respuesta es NO, sino que a partir de todo este código anterior, se crea una función (function NuevaVM { }) donde dentro de las claves se pone el código y hacemos una pequeña variación, en lugar de especificar el nombre de la máquina virtual, hacemos que lo coja del parámetro ($nombreVM = $args[0]) que se le pasará a la función. El resto es todo igual (no reproduzco todo el código de nuevo (…)).

function NuevaVM
{
   $nombreVM = $args[0]

   $plantillaVHDX = "D:\VMs\Plantillas\Windows2016coreplantilla.vhdx"
   $switch = "swExtern" #switch virtual donde conectar las máquinas virtuales.
...
   start-vm (Get-VM $nombreVM)
   vmconnect localhost $nombreVM
}

Si ahora se ejecuta este script, NO pasa nada, simplemente se ha definido una función en la consola, pero que no tiene una acción directa en el sistema. No se ha creado ninguna nueva máquina virtual ni nada de nada.

Creació màquines virtuals Hyper-V. Creant la funció de PowerShell.

Para crear una nueva máquina virtual utilizando nuestra función, se ejecuta el nombre de la función (NuevaVM) seguida del nombre de la nueva máquina virtual (srvDOS).

nuevavm srvDOS

Para cerrar, ¿y si quiero crear un entorno de varias máquinas virtuales a la vez? Por ejemplo una de Active Directory (srvDC), una para Microsoft SQL Server (srvSQL) y dos para servidor web (srvWEB1 y srvWEB2).

Se crea una función en que se le puedan pasar todos estos nombres (param) y vaya creando (foreach) una a una las máquinas virtuales utilizando la función anterior (NuevaVM).

function CrearEntornoAppWeb
{
   param([string[]] $VMs)
   foreach ($VM in $VMs)
   {
      write-host("Creando máquina virtual: " + $VM) -ForegroundColor Green
      NuevaVM $VM
   }
}

Es una función, por lo tanto tampoco ha hecho nada al ejecutarla, simplemente se ha dado de alta en el sistema. Pero ahora tenemos una instrucción muy potente, ponéos cómodos mientras va creando y arrancando las 4 máquinas virtuales sólo:

CrearEntornoAppWeb srvDC,srvSQL,srvWEB1,srvWEB2

creacio-vm-hyperv-automaticament-011

Una vez finaliza de trabajar para nosotros, tenemos las cuatro máquinas encendidas y a punto para trabajar.

Creació màquines virtuals Hyper-V. Entorn desplegat.

 

¡Y, claro, no escribiremos cada vez todas estas líneas de código!. Menú Archivo, Guardar como. La próxima vez sólo hay que abrirlo, y ejecutarlo para tener a disposición para la creación máquinas virtuales. También se puede añadir a otros procesos automáticos, el trabajo gordo ya está hecho. ¿Cuál será tu próximo paso?

 

Os dejo el script que he creado en esta entrada, colgado en el repositorio de GitHub, para no picar tanto código.

 

¿Te ha gustado el artículo? Lo puedes compartir en las redes sociales. También puedes dejar tu opinión, comentario o sugerencia. ¡Gracias!

Similar Posts by The Author:

 

8 comentaris per a
“Creación máquinas virtuales Hyper-V automáticamente”

  1. ¡Estupendo artículo, Josep Ma!

    Justo lo que necesitaba para mi lab doméstico…

    Solo una sugerencia: en los nombres de funciones, quizá sería una buena idea adherirse a las «best practices» de Microsoft y utilizar la combinación «Nombre-Verbo» o, para evitar colisiones de nombres, «Nombre-PrefijoVerbo».

    Por ejemplo, tengo una función similar que crea máquinas virtuales y plantillas para la infraestructura VMware de la empresa, y como «New-VM» ya está en uso (tanto por PowerCLI como por Hyper-V), mi función se llama «New-TPVM», siendo «TP» el prefijo que utilizamos para nuestras funciones PowerShell y que coincide con las siglas de la empresa.

    Una idea similar siguen los cmdlets de Active Directory, que utilizan el prefijo «AD» (New-ADUser, etc)

    En cualquier caso, enhorabuena por tu blog. Lo descubrí hace poco y realmente me viene como anillo al dedo, ya que en mi día a día trabajo con muchas tecnologías que aparecen en tus artículos (sistemas operativos de Microsoft, VMware, Veeam, Office 365, Hyper-V…)

    Un saludo,

    Manu

     
    1. Hola Manu, muchas gracias por tu aportación, la verdad es que se me había pasado y la encuentro de gran ayuda.

      En los próximos y tambien en este ya haré la adaptación.

      Saludos,

       
  2. buenas ,muy bueno el articulo,pero una consulta si en este caso las maquinas virtuales corrieran sobre un hypervisor vm esxi o vSphere ,como seria la activación de las maquinas virtuales.saludos

     
    1. Las debes activar igual que en cualquier otro hipervisor, por KMS (mediante proxy de red y activación automática) o MAK (asignando el Key manualmente a cada máquina).
      Lo que no te funcionaria es la activación por AVMA al no tener un hipervisor Microsoft licenciado.

       
  3. Muchas Gracias JMSolanes, buena explicación, talves te puedes realizar un articulo sobre mantenimiento de las maquinas virtuales en powershell

     
  4. JMSolanes como haces para habilitar el vmconnect, que debo de realizar para lograr levantar una VM con vmconnect, yo lo ejecuto en un Hyper-V Server 2016 Core pero me lanza el siguiente error:

    vmconnet : The term ‘vmconnet’ is not recognized as the name of a cmdlet, function, script file, or operable program.
    Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:1
    + vmconnet localhost WipoPublish
    + ~~~~~~~~
    + CategoryInfo : ObjectNotFound: (vmconnet:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

     
    1. Hola Angel,

      El VMConnect es la aplicación de conexión a la consola gráfica de una máquina virtual. En la versión CORE esta opción no existe. Para encender una máquina virtual debes utilizar el start-vm.

      Saludos,

       
Els comentaris estan tancats.