Skip to main content
This guide covers setting up Windows VMs on your own machine using Hyper-V. Great for development and testing.

Overview

For local testing, you can run multiple Windows 11 VMs using Hyper-V. This gives you full control over your automation environment.
Windows Sandbox only allows one instance at a time. For parallel testing, use Hyper-V VMs instead.

Prerequisites

  • OS: Windows 11 Pro/Enterprise/Education (Hyper-V not available on Home)
  • RAM: 16GB+ recommended (4GB per VM + host overhead)
  • CPU: SLAT support (most modern CPUs)

Step 1: Enable Hyper-V

Run in elevated PowerShell:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
Reboot when prompted. Verify by opening “Hyper-V Manager” from Start menu.

Step 2: Download Windows 11 ISO

1

Get the ISO

2

Download

Download the 64-bit ISO (90-day evaluation, free)
3

Save

Save to C:\ISOs\Win11Enterprise.iso

Step 3: Create Virtual Switch

In Hyper-V Manager → Virtual Switch Manager → New virtual network switch:
SettingValue
TypeExternal
NameExternal-Internet
External networkSelect your physical NIC
This gives VMs internet access and makes them reachable from host.

Step 4: Create Base VM

In Hyper-V Manager → Action → New → Virtual Machine:
SettingValue
Namecua-base-template
Generation2 (required for TPM/Windows 11)
Memory4096 MB (uncheck dynamic memory)
NetworkExternal-Internet
Virtual Hard Disk60 GB, dynamically expanding
InstallationMount the Windows 11 ISO
After creation, configure security:
  1. Right-click VM → Settings → Security
  2. Enable “Enable Trusted Platform Module”
  3. Secure Boot: Microsoft UEFI Certificate Authority
Start VM and install Windows 11.

Step 5: Configure Base VM

After Windows installation, configure the VM.

Create Local Account

Create a local admin account (e.g., cua-agent with your password). Avoid Microsoft account for simpler automation.

Enable Remote Desktop

Settings → System → Remote Desktop → Enable
Allow connections from any version of Remote Desktop.
Settings → Network & Internet → Ethernet → Edit IP settings
Example IPs for your VMs:
  • VM1: 192.168.1.101
  • VM2: 192.168.1.102
  • VM3: 192.168.1.103

Disable Windows Update (Optional)

Prevents surprise reboots during testing:
# Run as admin
Stop-Service wuauserv
Set-Service wuauserv -StartupType Disabled

Install Python 3.12

Use Python 3.12, NOT 3.13+ (pywin32 compatibility issues)
Download from python.org and install with “Add to PATH” checked.

Install Driver Dependencies

pip install pyautogui mss pillow rpaframework websockets

Clone and Setup Driver

cd C:\
git clone <your-repo-url> granite
cd granite\driver
pip install -r requirements.txt

Create Checkpoint

In Hyper-V Manager:
  1. Right-click VM → Checkpoint
  2. Name it clean-base-with-driver
This allows quick revert to clean state.

Step 6: Clone VMs

Export Base VM

  1. Shut down the base VM
  2. Right-click → Export
  3. Save to C:\Hyper-V\Exports\

Import as Copies

  1. Action → Import Virtual Machine
  2. Select the exported folder
  3. Choose “Copy the virtual machine (create a new unique ID)”
  4. Select new storage location

Configure Each Clone

For each cloned VM:
  1. Rename in Hyper-V Manager: cua-local-01, cua-local-02, etc.
  2. Start VM and change computer name
  3. Assign unique static IP
  4. Update client_machine_id in driver config (must be unique)

Step 7: Start VMs and Register Drivers

  1. Start all VMs in Hyper-V Manager
  2. In each VM, run the driver application
  3. Driver will auto-register with backend via WebSocket
  4. Verify machines appear in Driver Management

Step 8: Add RDP Credentials

For each registered VM, update RDP credentials so the agent can connect:
from backend.utils.mongo.vm_keys_mongodb import update_rdp_credentials

update_rdp_credentials(
    driver_machine_id="<id-from-mongodb>",
    rdp_username="cua-agent",
    rdp_password="your-password",
    rdp_external_ip="192.168.1.101",
    rdp_port=3389
)
Or update directly in MongoDB:
{
  "rdp_username": "cua-agent",
  "rdp_password": "your-password",
  "rdp_external_ip": "192.168.1.101",
  "rdp_port": 3389
}

Quick Reference Commands

# Start all CUA VMs
Get-VM -Name "cua-local-*" | Start-VM

# Stop all CUA VMs
Get-VM -Name "cua-local-*" | Stop-VM

# Check VM status
Get-VM -Name "cua-local-*" | Select Name, State, CPUUsage, MemoryAssigned

# Revert to clean checkpoint
Restore-VMCheckpoint -Name "clean-base-with-driver" -VMName "cua-local-01" -Confirm:$false

# Revert all VMs to checkpoint
Get-VM -Name "cua-local-*" | Restore-VMCheckpoint -Name "clean-base-with-driver" -Confirm:$false

Resource Planning

ConfigurationRAM per VMTotal VMsVM RAM UsageHost Available
16GB system4GB28GB~8GB
32GB system4GB312GB~20GB
32GB system4GB520GB~12GB

Troubleshooting

IssueSolution
Can’t RDP to VMCheck Windows Firewall allows RDP (port 3389)
VM not appearing in MongoDBVerify driver is running and WebSocket URL is correct
RDP connection fails from backendVerify rdp_external_ip matches VM’s actual IP
VM runs slowDisable dynamic memory, ensure host has RAM headroom
TPM error during Windows installEnable TPM in VM Settings → Security
90-day eval expiresCreate fresh VM from ISO, re-run setup steps
Network conflictsEnsure each VM has unique computer name and IP

Architecture Notes

The local Hyper-V setup integrates with the existing backend architecture:
  1. Driver Registration: Driver connects via WebSocket and calls register_or_update_driver_machine() automatically
  2. RDP Credentials: Stored in MongoDB, retrieved by agent via get_rdp_credentials()
  3. Job Execution: Backend dispatches jobs to VMs via the same job queue system
  4. No Backend Changes Required: The architecture is VM-agnostic; local Hyper-V VMs work identically to cloud VMs