Estamos planeando automatizar la creación de máquinas virtuales para nuestra infraestructura de compilación para que podamos:
- Escale los recursos de compilación según la demanda, por ejemplo, agregando más agentes de compilación cuando sea necesario y eliminándolos cuando no sea necesario
- Recree todo o parte del entorno de construcción si / cuando las máquinas mueren
- Duplicar el entorno de compilación cuando necesitamos una configuración de prueba
Uno de los pasos en este proceso es automatizar la creación de las imágenes base de VM (en nuestro caso, usando Hyper-V). Para eso tenemos un script que:
- Crea un nuevo VHDX desde ISO con el script Convert-WindowsImage . Actualmente estamos usando Windows 2012R2, pero buscaremos comenzar con 2016 tan pronto como esté disponible.
- Agrega un script desatendido al nuevo VHDX con toda la configuración básica que necesitamos
- Actualiza el VHDX con los últimos parches de Windows utilizando el script Apply-WindowsUpdate
- Crea una nueva máquina virtual Hyper-V basada en VHDX y la inicia
- Espera a que la VM arranque y espera que el servicio WinRM esté listo para aceptar conexiones remotas
- Espera a que Windows complete la configuración inicial y la configuración de los nuevos parches
- Aplica cualquier parche adicional
- Reinicia para completar la configuración de los últimos parches
- Espera a que Windows complete la configuración de los parches
- Empuja un script sysprep a la máquina e invoca ese script. Esto ejecuta sysprep y luego apaga la máquina
- Elimina la VM pero mantiene el VHDX
- Elimina los archivos sysprep y desatendido del VHDX y luego compacta el VHDX
- Mueve VHDX a la ubicación de la plantilla y marca como solo lectura
El problema que estamos experimentando está en los pasos 6 y 9. Idealmente, esperamos que se complete toda la configuración antes de reiniciar / apagar la máquina, pero no parece haber una forma de detectar que Windows ha terminado la etapa de configuración.
Al pasar por la interfaz de usuario, es muy claro cuando se realiza cualquiera de los pasos porque la interfaz de usuario de inicio de sesión no aparece hasta que el proceso esté listo. Sin embargo, cuando se utiliza WinRM para conectarse de forma remota a la máquina, esto es menos claro porque WinRM proporciona acceso a la máquina antes de que termine el trabajo de configuración.
Entonces, la pregunta es cuál es la forma más infalible de detectar a través de una conexión remota que Windows ha terminado de configurar actualizaciones, etc. para que podamos reiniciar / apagar la máquina sin causar problemas más adelante.
------ EDITAR -----
Al final, estamos usando una versión modificada de la respuesta de Katherine en que nuestro script también espera windeploy
y ngen
completa. Dado que eso ngen
no se completa hasta mucho después de que el sistema operativo haya terminado de inicializar, eso funciona, y como beneficio adicional, el VHDX final tendrá todo el .NET framework ngen-ed, lo que significa que no tenemos que lidiar con eso cuando creamos nuevos Máquinas virtuales del disco de plantilla. Tanto el script que usamos para crear la plantilla VHDX como los scripts para crear el entorno de prueba local están en github en caso de que alguien esté interesado.