Build Windows VM Template

This guide will help you to enable Windows VM support on the hosts of your platform. The guide’s steps should be performed on the Virtuozzo 7 based host that will be used for the Windows VM hosting.

1. Download the .iso image of the Windows server to your host node.

wget http://example.com/windows16.iso -o /vz/windows16.iso

2. Ensure that virtualization is enabled on the host by executing the following command:

grep --color "vmx\|svm" /proc/cpuinfo

virtualization check on host

If you get an empty response, the virtualization does not work on the host and should be enabled before proceeding further.

3. Create a new virtual machine (VM). Start by defining the required variables, then create, configure, and start VM:

Tip: Use comments (highlighted lines that start with #) for additional explanation on what each command does.

#VM name

name=windows2016

#Distribution. Use the “prlctl create qqq –distribution list” command to list available ones

distr=win-2016

#Disk size. Use the smallest possible size for the defined distribution

disksize=13G

#VNC port and credentials. They will be used during the OS installation

port=6500
vnc_password=passw0rd

#Path to the .iso image

ISO=/vz/windows16.iso

#Create VM:

prlctl create ${name} --distribution $distr --vmtype vm

#Configure Virtual Network Computing (VNC):

prlctl set ${name} --vnc-mode manual --vnc-port ${port} --vnc-passwd ${vnc_password}

#Configure disks:

prlctl set ${name} --device-set cdrom0 --image $ISO
prlctl set ${name} --device-del hdd0
prlctl set ${name} --device-add hdd --size $disksize
prlctl set ${name} --device-bootorder "cdrom0 hdd0 fdd0"

#Start VM and connect CD-ROM:

prlctl start ${name}
prlctl set ${name} --device-connect cdrom0

4. Install Windows OS and set up an admin account.

Use the port/password defined in the previous step and external host IP address to connect to the virtual machine via VNC. Ensure that the VNC port is allowed in the firewall.

Once connected, install Windows and set a password for the admin account as usual.

5. Install Virtuozzo Tools. Run the following command on the host:

prlctl installtools ${name}

Then, connect to VM using VNC and execute CD-ROM autorun.

install Virtuozzo Tools autorun

Reboot OS to apply changes.

6. Enable RDP and sysprep your OS. Run commands listed below one by one on the host (do not execute as code block):

#Connect to VM from a host using prlctl utility:

prlctl enter ${name}

#Start PowerShell session

powershell

#Enable RDP and open RDP port in brandmauer

Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0

Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
Note: 

If this command returns an error, run the following one instead:

netsh advfirewall firewall add rule name="allow RemoteDesktop" dir=in protocol=TCP localport=3389 action=allow

#Create the “unattend” file for sysprep:

New-Item u.xml

#Add content to u.xml. Execute command listed under the link:

https://dot.jelastic.com/download/graf/unattend.txt

Note: 

File u.xml is just an example and created for Windows Server 2016/2019. If needed, you can make changes to it.

Requirements for the image created with sysprep:

  1. accept LUA
  2. choose language
  3. create a user account (credentials will be changed after VM creation by Jelastic)

#Close PowerShell session

exit

#Run sysprep using previously created unattend file u.xml.

c:\windows\system32\sysprep\sysprep.exe /generalize /shutdown /oobe /unattend:c:\windows\system32\u.xml

Wait till VM is stopped (approximately 2-3 minutes).

7. Create a template.

#If needed, substitute windows2016 with the required template name

prlctl set ${name} --device-del net0
prlctl set ${name} --vnc-mode off
prlctl set ${name} --device-del cdrom0
prlctl clone ${name} --name windows2016 --template

#Show template UUID

prlctl list --template windows2016

8. Test template.

#VM name

NAME=myvm

#Template UUID

TEMPLATE=31c6244f-897e-474f-a9c4-b8dad926ca8e

#IP address

IP=10.10.10.10/24

#Administrator credentials

CREDENTIALS=Administrator:My-Secure-Passw0rd

#Create VM

prlctl create ${NAME} --ostemplate {$TEMPLATE}

#Configure limits, disk and networks

prlctl set ${NAME} --memsize 6000M --device-set hdd0 --size 20G --no-fs-resize
prlctl set ${NAME} --device-add net --type routed --mac auto --ipadd $IP --nameserver 1.1.1.1

#Start VM

prlctl start ${NAME}

#Wait for VM and OS to start

sleep 10
for i in $(seq 1 40); do prlctl exec ${NAME} tasklist | grep -i winlogon && break || sleep 3; done

#Change mapsbroker service startup type. It removes some warnings after the first OS start.

prlctl exec ${NAME} 'sc' 'config' 'mapsbroker' 'start=' 'demand'

#Resize file system

prlctl exec ${NAME} 'powershell.exe' '-noprofile' '-command' '$size = (Get-PartitionSupportedSize -DriveLetter C); Resize-Partition -DriveLetter C -Size $size.SizeMax'

#Set credentials

prlctl set ${NAME} --userpasswd ${CREDENTIALS}

Now, you can access VM using RDP.

#Connect, make some tests, stop, and delete tested VM

prlctl stop ${NAME}
prlctl destroy ${NAME}

#Delete VM used for template creation

prlctl destroy ${name}

9. Migrate template. Spread the template across all the hosts within the host group(s) that will provide Windows VM support.

prlctl migrate <template_uuid> root@<VZ7_server_IP_address_or_hostname>

That’s all. You have a fully functional Windows VM template on your hosts and are ready for the Windows VM hosting.

What’s next?