How to Create a Virtual Machine in Hyper-V on Windows Server 2012 R2

Creating virtual machines is the primary day-to-day task of a Hyper-V administrator. Windows Server 2012 R2 Hyper-V introduces Generation 2 VMs — which use UEFI firmware, support Secure Boot, and eliminate legacy hardware emulation — alongside the traditional Generation 1 VMs which provide broader OS compatibility. Knowing when to use each generation and how to configure VM properties correctly from the outset saves significant effort when troubleshooting or migrating workloads later.

This guide covers creating VMs via both Hyper-V Manager and PowerShell, configuring key properties (memory, CPU, networking, storage, boot order), and best practices for production VM configurations.

Prerequisites

  • Hyper-V role installed and configured (virtual switches already created).
  • An ISO file for the guest OS available on the host (in D:Hyper-VISO or on a network share).
  • Sufficient host RAM and disk space for the VM workload.
  • VM storage paths configured (from Set-VMHost).

Understanding Generation 1 vs Generation 2

Generation 1 uses emulated IDE controllers and a BIOS. Supported operating systems include all Windows versions from Windows XP onwards and most Linux distributions. Use Generation 1 for older OS versions or when compatibility is uncertain.

Generation 2 uses SCSI-only storage (no IDE), UEFI firmware with optional Secure Boot, and supports PXE boot via the synthetic network adapter. Supported for Windows Server 2012 and later and some modern Linux distributions. Use Generation 2 for all modern Windows Server workloads — it boots faster and has a simpler device model.

Step 1: Create a Generation 2 Virtual Machine via PowerShell

# Create a Generation 2 VM with a new VHDX disk
New-VM `
    -Name "WebServer01" `
    -Generation 2 `
    -MemoryStartupBytes 4GB `
    -NewVHDPath "D:Hyper-VVHDsWebServer01.vhdx" `
    -NewVHDSizeBytes 80GB `
    -SwitchName "External-Production" `
    -Path "D:Hyper-VVMs"

# Configure processor count (4 vCPUs)
Set-VMProcessor -VMName "WebServer01" -Count 4

# Enable Dynamic Memory (min 1 GB, startup 4 GB, max 8 GB)
Set-VMMemory -VMName "WebServer01" `
    -DynamicMemoryEnabled $true `
    -MinimumBytes 1GB `
    -StartupBytes 4GB `
    -MaximumBytes 8GB `
    -Buffer 20

# Attach the installation ISO
Add-VMDvdDrive -VMName "WebServer01" `
    -Path "D:Hyper-VISOWindowsServer2012R2.iso"

# Set boot order: DVD first, then hard disk
$dvd = Get-VMDvdDrive -VMName "WebServer01"
$hdd = Get-VMHardDiskDrive -VMName "WebServer01"
Set-VMFirmware -VMName "WebServer01" -BootOrder $dvd, $hdd

# Verify the VM configuration
Get-VM -Name "WebServer01" | Select-Object Name, Generation, State, MemoryStartup, ProcessorCount

Step 2: Create a Generation 1 Virtual Machine

# Create a Generation 1 VM (for older OS compatibility)
New-VM `
    -Name "LegacyApp01" `
    -Generation 1 `
    -MemoryStartupBytes 2GB `
    -NewVHDPath "D:Hyper-VVHDsLegacyApp01.vhdx" `
    -NewVHDSizeBytes 60GB `
    -SwitchName "External-Production" `
    -Path "D:Hyper-VVMs"

# Set processor count
Set-VMProcessor -VMName "LegacyApp01" -Count 2

# For Generation 1, the DVD drive is on the IDE controller by default
# Check the IDE controller layout
Get-VMIdeController -VMName "LegacyApp01"

# Attach ISO to the DVD drive (already on IDE Controller 1, port 0)
Set-VMDvdDrive -VMName "LegacyApp01" -Path "D:Hyper-VISOWindowsServer2012R2.iso"

Step 3: Configure Advanced CPU Settings

# Configure vCPU settings for a compute-intensive VM
Set-VMProcessor `
    -VMName "WebServer01" `
    -Count 4 `
    -Maximum 100 `
    -Reserve 25 `
    -RelativeWeight 100

# Enable NUMA topology exposure (for VMs with more than 8 vCPUs)
Set-VMProcessor -VMName "WebServer01" -ExposeVirtualizationExtensions $false

# Enable nested virtualisation (for VMs that will run Hyper-V inside)
Set-VMProcessor -VMName "WebServer01" -ExposeVirtualizationExtensions $true

# Set CPU affinity (bind VM to specific physical CPUs)
# This is set per-VM via host resource controls
Set-VMProcessor -VMName "WebServer01" -CompatibilityForMigrationEnabled $true

Step 4: Add Additional Virtual Hard Disks

# Create a new VHDX for data storage (dynamically expanding)
New-VHD `
    -Path "D:Hyper-VVHDsWebServer01-Data.vhdx" `
    -SizeBytes 200GB `
    -Dynamic

# Create a fixed-size VHDX for performance-critical storage
New-VHD `
    -Path "D:Hyper-VVHDsWebServer01-SQL.vhdx" `
    -SizeBytes 100GB `
    -Fixed

# Attach the data VHDX to the VM (Generation 2 uses SCSI controller)
Add-VMHardDiskDrive `
    -VMName "WebServer01" `
    -ControllerType SCSI `
    -ControllerNumber 0 `
    -ControllerLocation 1 `
    -Path "D:Hyper-VVHDsWebServer01-Data.vhdx"

# Verify all disks attached to the VM
Get-VMHardDiskDrive -VMName "WebServer01" | 
    Select-Object ControllerType, ControllerNumber, ControllerLocation, Path

Step 5: Configure VM Network Adapters

# List current network adapters
Get-VMNetworkAdapter -VMName "WebServer01"

# Rename the existing adapter
Rename-VMNetworkAdapter -VMName "WebServer01" -Name "Network Adapter" -NewName "Production NIC"

# Add a second network adapter (for a DMZ network or management)
Add-VMNetworkAdapter -VMName "WebServer01" -Name "Management NIC" -SwitchName "Internal-TestLab"

# Connect an existing adapter to a different switch
Connect-VMNetworkAdapter -VMName "WebServer01" -Name "Management NIC" -SwitchName "Internal-TestLab"

# Enable MAC address spoofing (required for nested virtualisation or NIC teaming inside VM)
Set-VMNetworkAdapter -VMName "WebServer01" -Name "Production NIC" -MacAddressSpoofing On

# Enable trunk mode for VLAN-aware VMs
Set-VMNetworkAdapterVlan -VMName "WebServer01" -Trunk -AllowedVlanIdList "100-200" -NativeVlanId 100

Step 6: Configure Checkpoints (Snapshots)

# Disable automatic checkpoints (recommended for production servers)
Set-VM -VMName "WebServer01" -AutomaticCheckpointsEnabled $false

# Set checkpoint type to Production (uses VSS for application-consistent snapshots)
Set-VM -VMName "WebServer01" -CheckpointType Production

# Create a manual checkpoint before making changes
Checkpoint-VM -VMName "WebServer01" -SnapshotName "Pre-Patch-2024-01-15"

# List checkpoints
Get-VMSnapshot -VMName "WebServer01" | Select-Object Name, CreationTime

# Restore to a checkpoint
Restore-VMSnapshot -VMName "WebServer01" -Name "Pre-Patch-2024-01-15" -Confirm:$false

# Delete an old checkpoint
Remove-VMSnapshot -VMName "WebServer01" -Name "Pre-Patch-2024-01-15"

Step 7: Start the VM and Monitor

# Start the VM to begin OS installation
Start-VM -Name "WebServer01"

# Connect to the VM console (opens in Hyper-V Manager / vmconnect)
vmconnect.exe localhost "WebServer01"

# Or connect via PowerShell (opens Enhanced Session if enabled)
$vm = Get-VM -Name "WebServer01"
vmconnect localhost $vm.Name

# Monitor VM resource usage
Get-VM -Name "WebServer01" | Measure-VM | 
    Select-Object VMName, AvgCPUUsage, AvgRAMUsage, MinRAMUsage, MaxRAMUsage

# Check all VM states on the host
Get-VM | Select-Object Name, State, CPUUsage, MemoryAssigned, Uptime | Format-Table

# Shut down VM gracefully (requires Hyper-V Integration Services installed in the guest)
Stop-VM -Name "WebServer01" -Force:$false

# Power off (hard power off — use only when guest shutdown fails)
Stop-VM -Name "WebServer01" -TurnOff

Summary

Creating and configuring virtual machines in Hyper-V on Windows Server 2012 R2 through PowerShell gives administrators complete, scriptable control over every aspect of a VM. The key decisions during VM creation are: choose Generation 2 for all modern Windows Server guests, enable Dynamic Memory with appropriate minimum and maximum values to allow the host to reclaim memory from idle VMs, use VHDX format for all virtual disks (never VHD on new deployments), attach VMs to the correct virtual switch for their network isolation requirements, and disable automatic checkpoints on production VMs (use Production checkpoints manually before maintenance windows). Always install Hyper-V Integration Services in the guest OS immediately after installation — they enable graceful shutdown, time synchronisation, and heartbeat monitoring.