# Create a Windows VM from an ISO in PCD

## Overview

Deploy Windows VMs directly from ISO files using <code class="expression">space.vars.product\_name</code> (<code class="expression">space.vars.product\_acronym</code>), eliminating manual installation and conversion workflows. Upload the Windows ISO and VirtIO drivers, configure installation volumes with optimized VM properties, execute the Windows installation with the required drivers, and generate reusable golden images for consistent enterprise deployments.

This approach streamlines Windows VM provisioning within <code class="expression">space.vars.product\_acronym</code> environments while maintaining standardized configuration management and automated provisioning capabilities.

## Prerequisites

**Environment Requirements**

* <code class="expression">space.vars.product\_acronym</code> access with Block Storage configured.
* Network connectivity and VLAN access.
* Image, volume, and VM creation permissions.

**Required Tools**

* PCD CLI (pcdctl) or OpenStack CLI version 6.3.0 and greater.
* product\_acronym web interface for console access

**Required Files**

* Windows ISO: Server 2012, 2016, 2019, 2022, or Windows 10.
* VirtIO Driver ISO: Latest stable from [Fedora VirtIO repository](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/), better performance on a Linux (QEMU-KVM) hypervisor.
* Verify file integrity using checksums

#### Step 1: Upload Images

1. **Upload Windows Installation ISO**

Run the following command to upload a Windows ISO (for example, Windows Server 2012, 2016, 2019, 2022, or Windows 10) to the <code class="expression">space.vars.product\_acronym</code> Image service.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl image create "windows-installation-iso" --os-interface admin --insecure \
  --disk-format iso \
  --container-format bare \
  --file /path/to/windows-installation.iso
```

{% endtab %}
{% endtabs %}

2. **Upload VirtIO Driver ISO**

Run the following command to upload the VirtIO driver ISO to the <code class="expression">space.vars.product\_acronym</code> Image service.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl image create "virtio-driver-iso" --os-interface admin --insecure \
  --disk-format iso \
  --container-format bare \
  --file /path/to/virtio-win.iso
```

{% endtab %}
{% endtabs %}

#### Step 2: Create Volumes

{% hint style="info" %}
**NOTE**

If you do not specify a volume type <code class="expression">space.vars.product\_name</code> uses `__DEFAULT__`, and you are adding `--type <volume-type>` to the `volume create` command to store volumes on block storage.
{% endhint %}

1. Create the installation media volume.

This creates a bootable volume that contains the Windows installation media.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl volume create --image windows-installation-iso --size 10 --bootable windows-installation-volume --insecure
```

{% endtab %}
{% endtabs %}

2. Create VirtIO driver media volume.

This creates a bootable volume that provides VirtIO drivers during Windows installation.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl volume create --image virtio-driver-iso --size 2 virtio-driver-volume --insecure
```

{% endtab %}
{% endtabs %}

3. Create Windows OS Target volume.

This creates a target disk where Windows is being installed.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl volume create --size 40 --bootable windows-os-target-volume --insecure
pcdctl volume set \
  --image-property hw_boot_menu=true \
  --image-property hw_firmware_type=uefi \
  --image-property hw_machine_type=q35 \
  --image-property hw_tpm_model=tpm-crb \
  --image-property hw_tpm_version=2.0 \
  --image-property hw_cdrom_bus=sata \
  --image-property hw_disk_bus=virtio \
  --image-property hw_scsi_model=virtio-scsi \
  --image-property os_secure_boot=required \
  --image-property os_type=windows \
  --image-property hw_video_model=qxl \
  windows-os-target-volume
```

{% endtab %}
{% endtabs %}

#### Step 3: Launch VM using the created volumes

This step creates a virtual machine with the previously created volumes. The VM is configured as follows:

* **Booting from the Windows installation ISO** (`device_type=cdrom`): The VM is loading the Windows installer.
* **Attaching the VirtIO driver ISO**`(device_type=cdrom`): The VM is providing essential drivers during the installation.
* **Using the target volume as the installation disk** (`device_type=disk`): The VM is serving this disk as the destination for the Windows OS installation.

The properties specified in the command ensure that the VM is booting correctly and remains compatible with Windows installation requirements.

{% tabs %}
{% tab title="Bash" %}

```bash
openstack server create --insecure --flavor m1.xlarge --network <NETWORK_NAME_OR_UUID> \
  --block-device source_type=volume,uuid=$(openstack volume show windows-os-target-volume -f value -c id --insecure),destination_type=volume,device_type=disk,boot_index=0 \
  --block-device source_type=volume,uuid=$(openstack volume show windows-installation-volume -f value -c id --insecure),destination_type=volume,device_type=cdrom,boot_index=1 \
  --block-device source_type=volume,uuid=$(openstack volume show virtio-driver-volume -f value -c id --insecure),destination_type=volume,device_type=cdrom,boot_index=-1 \
  --availability-zone <PCD-Cluster-Name> \
  <VM-Name>
```

{% endtab %}
{% endtabs %}

Replace `<NETWORK_NAME_OR_UUID>` with the appropriate network name or UUID in your environment. Replace `<vm-name>` with the desired name for your VM. Replace `<PCD-Cluster-Name>` with your PCD cluster name.

The `pcdctl volume show` command is referencing the previously created volumes to ensure correct attachment.

#### Step 4: Configure the VM

1. **Initial Boot Process**

Access the VM console from the <code class="expression">space.vars.product\_acronym</code> UI.

* Press **Enter** at the boot prompt
* Select **Boot Manager** and then press **Enter.**

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-c7643c374144b9dcb01dd3d5989fb22e1f94d312%2Fpyz7ez9ip34bcjzbtz82l8t8a68kbkb7tcugx9wh8zb0xgpvj9aqp0x3syep3ti1.png?alt=media" alt=""><figcaption></figcaption></figure>

* Select **UEFI QEMU QEMU CD-ROM** and then press **Enter**.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-e251900b6d2b8fed173f84163a5bd36fbf117831%2F3dd9ssokax7goywif3ewv6sbz2fz5ooalvlkzt35sn89zymsikm1k9dz2726xyti.png?alt=media" alt=""><figcaption></figcaption></figure>

* Press any key to boot from CD.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-95475d26d4bb49cfd8a8991781204f876a66e30a%2Fqkksvklxvxkn65shm2jm3beh17ez7eodfeggq66bsosg3bhtg6lf445ph9czvewf.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-4ece0cc508c54c6175c3d2b07d764451248c7789%2Fnh7oj35e7wjz86g57h86vdcldpqg4i931jgqfvqs48065btvw7jb3qbc1z0vq4z5.png?alt=media" alt=""><figcaption></figcaption></figure>

The Windows installer is loading. This occurs only during the first boot.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-7b45c31441a326c88d0fe053cd8c142e2009a1e8%2Fx5586sgvp6ymeida6xahze3yu2x2s97g9bpj5qj4ndl2zf4ya8p1mjl3c28oxr85.png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**NOTE**

VirtIO drivers required for optimal performance.
{% endhint %}

2. **Install VirtIO Drivers**

During Windows installation:

* Select **Browse** when prompted for storage drivers.
* Navigate to VirtIO driver ISO identified by the Windows version you are installing, for example `D:\amd64\2k19` for Windows Server 2019.
* Select and install VirtIO SCSI driver.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-7b45c31441a326c88d0fe053cd8c142e2009a1e8%2Fx5586sgvp6ymeida6xahze3yu2x2s97g9bpj5qj4ndl2zf4ya8p1mjl3c28oxr85.png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**NOTE**

VirtIO drivers required for optimal performance.
{% endhint %}

3. **OPTIONAL: Disable Secure Boot and vTPM**

Certain operating systems like Windows 11 require TPM and Secure Boot. If your VM does not have Secure Boot or a TPM but you still want to continue the installation, you can bypass these checks. To proceed, follow these steps:

* On the OS selection page, press Shift+F10 to open a command prompt.
* In the command prompt, type **regedit** and press **Enter** to launch the **Registry Editor**.
* On the **Registry Editor**, navigate to **HKEY\_*****LOCAL*****\_ MACHINE > SYSTEM > Setup** folder.
* Create a new key named **LabConfig** as a part of the **Setup** folder.
* Within the **LabConfig** key, create two new **REG\_DWORD** entries and set the values to `1`:
  * BypassTPMCheck
  * BypassSecureBootCheck
* Close the Registry Editor and the command prompt and continue with the Windows installation.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-63b508c0e04a6a722fbb3f344db98bc381ff08ee%2F1t6em6drvqp1j3mbqlmzb8piycm80taawb2wmt39o53uesk6rn6010z06p51uemh.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-a4bf5ee976036fd0dd6daaef8119309c64aea7af%2Fxc56pjz06v0rrdcup1gp7xmk0bkq92wxnp95yqdqt26qlxdc9fyzj9618pimqmgz.png?alt=media" alt=""><figcaption></figcaption></figure>

4. **Install Network and Other Required Drivers**

After Windows installation completes, install the necessary drivers to enable network connectivity and other devices.

* Access **Device Manager**.
* Right-click **Ethernet Controller** and select **Update Driver Software**.
* Browse to the VirtIO path (for example, `E:\NetKVM\2k16\`) and complete the installation.
* Repeat the process for any remaining devices listed in **Device Manager**.

5. **Verify VirtIO Driver Installation**

* Access **Device Manager** and then navigate to **System devices > VirtIO driver**.
  * If the VirtIO driver appears in the list, the driver is already installed.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-b75b44b752f2386bb05b71843269df7bce386834%2Fs4d0a5bzofrq8gpyxwydmy085aq7rej35jh0ces1awa4ozjl7pqsezt6x7rv9nut.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-31797551e3cdd94eff42c989c24d988119d1bb7c%2Ffrmnmgj3ll9gq8ht239k9q3w31qzhlu2brjkbf95apa8p3leq3dbgu9cxul9hb5z.png?alt=media" alt=""><figcaption></figcaption></figure>

* If it does not appear, continue with the following steps.
  * Download the VirtIO setup package from [Index of /groups/virt/virtio-win/direct-downloads](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/).
  * Run **virtio-setup** to install the drivers.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-91c5924227fe9dba4fcb030c1e3f43221bace91a%2F8ign1k03s8zeomjcpo758aiqc9ctusvo111x3k8o7s67vok69vdvo8nmxu0ffl46.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-daafbfc02e96241a9f7476f6252c7df0bd7f8f8e%2F792s9nege6ulowi8b3yutqgdhblf1dt37nyt2b8sh5oz1cd4yt1g15fkmefjwhdq.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-86ad9136b69eab4015642f9f9eca49fec4642954%2Fo9as1exjhulu0zgodq21k5go1niewpvhf4j1boeb7mepuu76gkszkzmhwuo7vb9l.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-d27f27e915e54a391f0de70852d85e9b142e2d48%2Fi7gcf3nunndnsk47fc5yp26dq8650mar1bop70rgr2y1hs77yeuwnc48x89mdn7y.png?alt=media" alt=""><figcaption></figcaption></figure>

* After installation is complete, navigate back to **Device Manager** > **System devices** to verify that the VirtIO driver is listed.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-66722e1b381cc7a02c6433d7e4b557b4ce764716%2F5f1uo5o9nhjptdkx5o6r1dcfnqp4thvax9tknnr4yvn0r1nszp57gd6iiqn92jea.png?alt=media" alt=""><figcaption></figcaption></figure>

6. **Install Cloudbase-Init**

* Download and run [Cloudbase-Init](https://cloudbase.it/cloudbase-init/) to enable automated configuration for future VMs. <code class="expression">space.vars.product\_acronym</code> uses Cloudbase-Init to set the initial Administrator password during VM deployment.
* Select the option to run **s ysprep** to create a generalized golden image.
* Allow the VM to power off automatically once the process is complete.

<figure><img src="https://1100565312-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIYcmHH6U169jTwihxwwy%2Fuploads%2Fgit-blob-6d5337f154febe9727121b4835f387bedd0c6a76%2Fe5jpziani9u2cjftdbru8nomb9bo3oy0qqjxz2srigs8s1rqcg1gkna53vfcu82f.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Step 5: Create Golden Image

1. **Detach the Windows Installer and VirtIO drivers:** Detach the windows-installation-volume and virtio-driver-volume. This leaves your VM with windows-os-target-volume with windows installed. This can be done from the UI
2. **Create a Glance Image from the Installation Volume:** Navigate to the windows-os-target-volume in the volumes page in the UI and select the action to `Upload as Image`.
3. **Set Image Properties:** Set the required properties to ensure the VM boots correctly. This can also be done in the UI using the `Edit Properties` option.

{% tabs %}
{% tab title="Bash" %}

```bash
pcdctl --os-interface admin --insecure image set <windows-image-name> \
  --property hw_boot_menu=true \
  --property hw_firmware_type=uefi \
  --property hw_machine_type=q35 \
  --property hw_tpm_model=tpm-crb \
  --property hw_tpm_version=2.0 \
  --property hw_disk_bus=virtio \
  --property hw_scsi_model=virtio-scsi \
  --property hw_vif_model=virtio \
  --property os_secure_boot=required \
  --property os_type=windows \
  --property hw_video_model=qxl
```

{% endtab %}
{% endtabs %}

A reusable golden image is now created and can be used for future Windows VM deployments, allowing you to quickly provision new VMs without having to repeat the installation process.

#### Step 6: Deploy a VM from the golden image

Refer to the [Deploy Vms On Your Virtualized Cluster](https://docs.platform9.com/private-cloud-director/2025.10/tutorials/deploy-vms-on-your-virtualized-cluster) guide to deploy a VM with the new golden image.
