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 the platform is the Datacenter Edition license, which is assigned for a whole host and allows you to create as many VMs inside as you need. You’ll need a separate Datacenter Edition license for each host with the Windows VM support.

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

This guide is suitable for both Windows Server 2019 and 2022 templates.

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 2019 to your host node.

1
wget http://example.com/windows19.iso -o /vz/windows19.iso
Note: It’s required to include English localization (alongside the preferred native one) in your Windows image to ensure the most comprehensive coverage of clients and allow the Support Team to investigate issues in case of necessity.

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

1
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

1
name=buildVMtemplate

#Distribution. Use the “prlctl create myvm --distribution list” command to list available ones

1
distr=win-2019

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

1
disksize=13G

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

1
2
port=6500
vnc_password=passw0rd

#Path to the .iso image

1
ISO=/vz/windows19.iso

#Create VM:

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

#Configure Virtual Network Computing (VNC):

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

#Configure disks:

1
2
3
4
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:

1
2
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.

Note: In order to allow Windows VM resizing, ensure that drive “C:” is the last one on the disk.

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

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

1
prlctl enter ${name}

#Start PowerShell session

1
powershell

#Enable RDP and open RDP port in brandmauer

1
2
3
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:

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

#Create the “unattend” file for sysprep:

1
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 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 the platform)

#Close PowerShell session

1
exit

Tip: You can apply any additional modifications to your OS.

If you require Internet access to make the necessary changes, it can be configured in the following way:

1
2
3
4
5
prlctl stop ${name}
prlctl set ${name} --device-del net0
prlctl set ${name} --device-add net --type routed --mac auto
prlctl set ${name} --device-set net0 --ipadd <IP ADDRESS> --nameserver <DNS SERVER IP ADDRESS>
prlctl start ${name}

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

1
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 windows2019 with the required template name

1
2
3
4
prlctl set ${name} --device-del net0
prlctl set ${name} --vnc-mode off
prlctl set ${name} --device-del cdrom0
prlctl clone ${name} --name windows2019tmp --template

#Show template UUID

1
prlctl list --template windows2019tmp

8. Test template.

#VM name

1
NAME=myvm

#IP address

1
IP=10.10.10.10/24

#Administrator credentials

1
CREDENTIALS=Administrator:My-Secure-Passw0rd

#Create VM

1
prlctl create ${NAME} --ostemplate windows2019tmp

#Configure limits, disk and networks

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

1
prlctl start ${NAME}

#Wait for VM and OS to start

1
2
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.

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

#Resize file system

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

#Set credentials

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

Now, you can access VM using RDP.

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

1
2
prlctl stop ${NAME}
prlctl destroy ${NAME}

#Delete VM used for template creation

1
prlctl destroy ${name}

9. Migrate template. Spread the template across all the hosts within the host group(s) that will provide Windows VM support. For each of these hosts, perform the following steps:

#Create template clone. Currently, only “windows2019” template name is supported

1
prlctl clone windows2019tmp --name  windows2019 --template

#Migrate clone to another host

1
prlctl migrate windows2019 root@<VZ7_server_IP_address_or_hostname>

If you need to add a Windows template to the current host - create a clone but do not migrate it.

10. Delete tmp template. After adding a template to all the needed hosts, perform a clean-up and remove the temporary image.

1
prlctl delete windows2019tmp

That’s all. You have a fully functional Windows VM template on your hosts and are ready to proceed with the Windows VM Hosting configuration.

What’s next?