Build Windows VM Template

This guide will help you to enable Windows VM support on the hosts of your platform. Based on your needs, you can configure a separate host exclusively for Windows hosting or use an existing one for mixed Windows VM and Linux containers hosting.

Windows License

Windows is a proprietary software owned by Microsoft, so you need to purchase a license in order to use and offer it to your customers. License type and price depends on your particular use case and agreement with Microsoft.

The most common option when integrating Windows with Jelastic PaaS is the Datacenter Edition license, which is assigned for a whole host and allows you to create as many VMs inside as you need. If you just want to test the implementation or have a small client base interested in Windows hosting, the Server Standard license can be issued per VM.

Note: This is just overview information, all the pricing and usage details are determined by your agreement with Microsoft.

Windows Template

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 -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


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


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


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


#Path to the .iso image


#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


#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"

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:


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


#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


#Template UUID


#IP address


#Administrator credentials


#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

#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?