Una necesidad que solemos tener es como subir nuestras maquetas de Windows personalizadas a Azure, pues vamos a ver qué pasos realizar para poder tenerlas.
Introducción
Partiremos de que tenemos una imagen en Hyper-V en nuestros servidores locales.
Azure permite máquinas de generación 1 y 2 (Diferencias) y formato de disco VHD.
También necesitaremos un Storage Account para subir nuestra imagen a Azure.
Prepara máquina para Azure
Comprobar archivos del sistema.
sfc.exe /scannow

Quitar el proxy WinHTTP.
netsh.exe winhttp reset proxy

Borrar rutas estáticas.
# Ver tabla de rutas
route.exe print
# Borrar ruta
route.exe delete xxx.xxx.xxx.xxx

Directiva SAN disco
diskpart.exe
DISKPART> san policy=onlineall
DISKPART> exit

Establecer Hora en UTC.
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation -Name RealTimeIsUniversal -Value 1 -Type DWord -Force
Establecer Energía alto rendimiento.
powercfg.exe /setactive SCHEME_MIN
Cambiar variable de TEMP y TMP.
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -Name TEMP -Value "%SystemRoot%\TEMP" -Type ExpandString -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -Name TMP -Value "%SystemRoot%\TEMP" -Type ExpandString -Force
Comprobar servicio.
Get-Service -Name BFE, Dhcp, Dnscache, IKEEXT, iphlpsvc, nsi, mpssvc, RemoteRegistry, w32time |
Where-Object StartType -ne Automatic |
Set-Service -StartupType Automatic
Get-Service -Name Netlogon, Netman, TermService |
Where-Object StartType -ne Manual |
Set-Service -StartupType Manual
Configuración Escritorio Remoto
Establecemos la configuración necesaria para el funcionamiento de RDP.
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name fDenyTSConnections -Value 0 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name PortNumber -Value 3389 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name LanAdapter -Value 0 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name UserAuthentication -Value 1 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name KeepAliveEnable -Value 1 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name KeepAliveInterval -Value 1 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name KeepAliveTimeout -Value 1 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name fDisableAutoReconnect -Value 0 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name fInheritReconnectSame -Value 1 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name fReconnectSame -Value 0 -Type DWord -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Winstations\RDP-Tcp' -Name MaxInstanceCount -Value 4294967295 -Type DWord -Force
Eliminar certificados autofirmados.
if ((Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp').Property -contains 'SSLCertificateSHA1Hash')
{
Remove-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name SSLCertificateSHA1Hash -Force
}
Configuración Firewall
Establecemos la configuración necesaria en el Firewall.
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True
Enable-PSRemoting -Force
Set-NetFirewallRule -Name WINRM-HTTP-In-TCP, WINRM-HTTP-In-TCP-PUBLIC -Enabled True
Set-NetFirewallRule -Group '@FirewallAPI.dll,-28752' -Enabled True
Set-NetFirewallRule -Name FPS-ICMP4-ERQ-In -Enabled True
New-NetFirewallRule -DisplayName AzurePlatform -Direction Inbound -RemoteAddress 168.63.129.16 -Profile Any -Action Allow -EdgeTraversalPolicy Allow
New-NetFirewallRule -DisplayName AzurePlatform -Direction Outbound -RemoteAddress 168.63.129.16 -Profile Any -Action Allow
Comprobación máquina
Chequeamos la coherencia del disco.
chkdsk.exe /f
Configuramos las opciones de arranque.
cmd
bcdedit.exe /set "{bootmgr}" integrityservices enable
bcdedit.exe /set "{default}" device partition=C:
bcdedit.exe /set "{default}" integrityservices enable
bcdedit.exe /set "{default}" recoveryenabled Off
bcdedit.exe /set "{default}" osdevice partition=C:
bcdedit.exe /set "{default}" bootstatuspolicy IgnoreAllFailures
#Enable Serial Console Feature
bcdedit.exe /set "{bootmgr}" displaybootmenu yes
bcdedit.exe /set "{bootmgr}" timeout 5
bcdedit.exe /set "{bootmgr}" bootems yes
bcdedit.exe /ems "{current}" ON
bcdedit.exe /emssettings EMSPORT:1 EMSBAUDRATE:115200
exit
Habilitamos la configuración de volcado de memoria.
# Set up the guest OS to collect a kernel dump on an OS crash event
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name CrashDumpEnabled -Type DWord -Force -Value 2
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name DumpFile -Type ExpandString -Force -Value "%SystemRoot%\MEMORY.DMP"
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name NMICrashDump -Type DWord -Force -Value 1
# Set up the guest OS to collect user mode dumps on a service crash event
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps'
if ((Test-Path -Path $key) -eq $false) {(New-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting' -Name LocalDumps)}
New-ItemProperty -Path $key -Name DumpFolder -Type ExpandString -Force -Value 'C:\CrashDumps'
New-ItemProperty -Path $key -Name CrashCount -Type DWord -Force -Value 10
New-ItemProperty -Path $key -Name DumpType -Type DWord -Force -Value 2
Set-Service -Name WerSvc -StartupType Manual
Comprobamos el repositorio de WMI.
winmgmt.exe /verifyrepository

Instalación Azure VM Agente
Descargamos e instalamos el Agente de Azure
https://go.microsoft.com/fwlink/?LinkID=394789

Generalización disco
Un vez tengamos la máquina preparada, lanzaremos un sysprep a la maquina para dejarla preparada para los despliegues.
Si queremos subir una máquina tal cual no hace falta que hagamos el sysprep.

Convertir Disco
Antes de subir la imagen tendremos que tenerla en formato VHD y tipo Fijo.
Con Powershell
Lanzaremos el siguiente comando para convertirlo con el disco de origen y ubicación del nuevo y esperamos que se convierta.
Convert-VHD -Path C:\HD\Disco.vhdx -DestinationPath C:\HD\DiscoFijo.vhd -VHDType Fixed

Con Consola
Convertiremos el disco en VHD y tipo Fixed si no lo tenemos todavía, Pulsamos en Edit Disk, seleccionamos nuestro disco y seleccionamos la opción de Convert.

Seleccionamos formato VHD.

Seleccionamos tipo Fixed.

Seleccionamos el fichero de salida.

Y esperamos a que se convierta.

Problema arranque pantalla negro
Al convertir de VHDX a VHD la maquina no arrancará, necesitaremos reparar el boot de arranque, os dejo el post para solucionarlo.

Subir VHD
Ahora subimos el VHD a nuestro Blob storage podemos usar Storage Explorer, el portal azure, o podemos buscar como subir con Poweshell.
Storage Explorer
Nos conectaremos a nuestra subscripción, en nuestro Storage Account > Blob Containers, nos creamos una carpeta y arrastramos nuestro disco dentro (tipo Active blobs) y esperamos a que se copie.

Azure Portal
Abrirmos nuestro Storage Account en Azure portal y pulsamos en “Upload”, selecionamos el disco.
La copia es mucho mas lenta.

Crear Imagen en Azure
Para crear nuestra imagen vamos a necesitar la URL del disco, podremos verla en nuestro Storage Account > container > fichero VHD (desplegamos las opciones en el boton ···) > Propiedades > Copiamos la URL.

Buscamos “images”

Pulsamos sobre “+ Create”.

Rellenamos nuestro valores, y en Storage blob pegamos la URL del Disco. (podemos pulsar en browse para buscarla pero a veces no funciona).
Rellenamos Tags si los usamos y Creamos la imagen.

Ya tendremos disponible nuestra imagen en Azure para desplegar máquinas.
