Pete Hinchley: Install and Configure Hyper-V on Windows Server 2012 R2 using PowerShell

This post will demonstrate the steps required to install and configure a simple Hyper-V deployment on Windows Server 2012 R2 (Server Core).

The following assumptions apply:

To use the Hyper-V management console on Windows Server 2012 R2 (Server Core), it is necessary to reconfigure the server in "minimal-UI" mode. This can be done by running the following commands from an elevated PowerShell prompt:

$mount = Mount-DiskImage -ImagePath D:\Media\en_windows_server_2012_r2_with_update_x64.iso -PassThru
$drive = ($mount | Get-Volume).DriveLetter + ':'

mkdir D:\Mount
dism /Mount-Wim /WimFile:$drive\sources\install.wim /MountDir:D:\Mount /Index:2 /ReadOnly
Add-WindowsFeature -Name Server-GUI-MGMT-Infra -Source D:\Mount\windows\winsxs
dism /UnMount-Wim /MountDir:D:\Mount /Discard
rmdir D:\Mount

DisMount-DiskImage -ImagePath D:\Media\en_windows_server_2012_r2_with_update_x64.iso

Before rebooting the server, let's prevent Server Manager from auto-starting at logon:

New-ItemProperty -Path HKCU:\Software\Microsoft\ServerManager -Name DoNotOpenServerManagerAtLogon -PropertyType DWORD -value "0x1" –Force

And now restart:


To install the Hyper-V feature:

Add-WindowsFeature -Name Hyper-V -IncludeManagementTools

After the server reboots, you could launch the Hyper-V management console from a command prompt with the following command (but why bother when you can do everything via PowerShell):


Use the following command to create a Hyper-V virtual switch (note: your network connection to the server will drop briefly):

New-VMSwitch -Name LAB -NetAdapterName "Ethernet" -AllowManagementOS $true -Notes "Hyper-V Management, Virtual Machines"

To create a "generation 2" virtual machine named EDWARD with a 140 GB hard drive, 2 processors, and dynamic memory (8 GB startup, 4 GB minimum and 16 GB maximum):

$name = "EDWARD"
$path = "D:\VMs"

if (-Not (Test-Path $path)) { New-Item -Type Directory $path }

$vm = New-VM -Name $name -Path $path -Generation 2 -MemoryStartupBytes 8GB -NewVHDPath "$path\$name\Virtual Hard Disks\$name.vhdx" -NewVHDSizeBytes 140GB -SwitchName LAB
$vm | Set-VM -DynamicMemory -MemoryMinimumBytes 4GB -MemoryMaximumBytes 16GB -ProcessorCount 2

The commands will create the following files/folder structure:

D:\VMs\EDWARD\Virtual Hard Disks\EDWARD.vhdx
D:\VMs\EDWARD\Virtual Machines\<GUID>.xml
D:\VMs\EDWARD\Virtual Machines\<GUID>\

To disable the "time synchronization" integration service:

$vm | Disable-VMIntegrationService -Name "Time Synchronization"

To add a DVD-ROM and bind it to an ISO:

$vm | Add-VMDvdDrive -PassThru | Set-VMDvdDrive -Path "D:\Media\en_windows_server_2012_r2_with_update_x64_dvd_6052708.iso"

The resultant boot order will be Network Adapter, Hard Drive, DVD Drive. This is good.

To connect to the virtual machine:

vmconnect.exe localhost $VM.Name

Finally, to start the virtual machine:

Start-VM $vm

The virtual machine will boot. Press any key to boot from the DVD. You are now underway...

As an added bonus, let's assume the physical host on which you've installed Hyper-V has two network adapters, each connected to a separate network or VLAN. You decide you want to route traffic between the networks using SmallWall, a FreeBSD router and firewall. The first step is to create a new virtual switch, which we will name PUBLIC. The AllowManagementOS property is set to False to prevent direct access to the switch from the Hyper-V host.

New-VMSwitch -Name PUBLIC -NetAdapterName "Ethernet 2" -AllowManagementOS $false -Notes "Edge Router"

The next step is to create a "generation 1" virtual machine for hosting SmallWall (which I will call CHARLES). A generation 1 virtual machine is necessary as SmallWall only supports legacy network adapters. The virtual machine is allocated a maximum of 512 MB of memory, assigned a 32 MB hard drive (SmallWall needs as little as 16 MB), and configured with two network adapters (the first bound to the LAB switch, and the second to the PUBLIC switch). The SmallWall ISO is mounted, and the system startup order modified. Finally, a console connection is established, and the server is started.

$name = "CHARLES"
$path = "d:\VMs"

$vm = New-VM -Name $name -Path $path -Generation 1 -MemoryStartupBytes 256MB -NewVHDPath "$path\$name\Virtual Hard Disks\$name.vhdx" -NewVHDSizeBytes 32MB -SwitchName LAB -BootDevice LegacyNetworkAdapter

$vm | Set-VM -DynamicMemory -MemoryMinimumBytes 128MB -MemoryMaximumBytes 512MB -ProcessorCount 1
$vm | Add-VMNetworkAdapter -IsLegacy $true -SwitchName PUBLIC
$vm | Disable-VMIntegrationService -Name "Time Synchronization"
$vm | Get-VMDvdDrive | Set-VMDvdDrive -Path "D:\Media\smallwall-generic-pc-1.8.3.iso"
$vm | Set-VMBios -StartupOrder @("IDE","CD","LegacyNetworkAdapter","Floppy")

vmconnect.exe localhost $VM.Name
Start-VM $vm

You can now proceed with the installation of SmallWall.