Hyper-V Scripting in Windows 8

For last year’s FAQs, Tips, and Tricks, I detailed one way you can quickly spin up new VMs via scripting, using System Center Virtual Machine Manager’s “Rapid Provisioning”. In day 3 or our 12 days of Tips and Tricks, I’m going to show you what this might look like in Windows 8, and this can all be done using the in-box Hyper-V and Failover Clustering cmdlets without any need for System Center.

First of all, a quick look at the new Hyper-V cmdlets.

Warning – this example is based on pre-release Windows 8 code, and is subject to change before shipping. This is just a point in time example that may not work in 6 months. Use at your own risk, and validate in the lab.

New-VM, Set-VM

At the most basic level, you only really need to use a couple cmdlets to get your VM up and running (and one additional cmdlet to cluster it): New-VM, and Set-VM

$newvm = NEW-VM -Name $VMNAME -Path  C:\ClusterStorage\Volume1\ -VHDPath "C:\ClusterStorage\Volume1\$VMNAME\c.vhdx" -SwitchName "Guest"
Set-VM $newvm -ProcessorCount 4 -DynamicMemory -MemoryMinimumBytes 1GB -MemoryStartupBytes 2GB -MemoryMaximumBytes 8GB
Set-VMNetworkAdapterVlan -VMName $VMName -VlanId 123 -VMNetworkAdapterName "Network Adapter" -Access
Add-ClusterVirtualMachineRole -Cluster MYCLUSTER -VMName $VMName

As always, the beauty of PowerShell is that you can take this little snippet and bring it into something much more wondrous and magical with just a little bit of work. In my case, I have a workflow that will do the following:

  1. Create a PS-Session to a host within my cluster
  2. Create a new folder on my Cluster Shared Volume based on the VM parameter
  3. Copy the Gold Image VHD to the Clustered Shared Volume
  4. Mount the VHD on the parent partition
  5. Inject the Computer Name and IP Address, and “IP of the Provisioning Server” information into the VHDx (to create a firewall rule in real-time)
  6. Unmount the VHD
  7. Create the VM (using above code)
  8. Power on the VM
  9. Wait a bit of time for the VM to run through it’s autounattend and come online
  10. Remotely connect to the VM through WS-MAN and WMI to finish build (domain join, Windows Updates, role/feature installation)

With about 25 lines of PowerShell, you can have your own highly flexible Scripted Cloud solution without installing any additional software! (My script is actually about 300 lines, due to lots of debugging code, error handling, et cetera, but the work is done in about 25 lines.)

An example of how it all works:

  • Create a PS-Session to a host within my cluster
$s = New-PSSession -ComputerName MYHYPERVBOX
Invoke-Command -Session $s -ScriptBlock {
param ($VMName, $IP,$ProvIP)
####
}  -ArgumentList $VMName,$IP,$ProvIP

The following steps happen within the PS-Session braces above.

  • Create a new folder on my Cluster Shared Volume based on the VM parameter
mkdir C:\ClusterStorage\Volume1\$VMNAME
  • Copy the Gold Image VHD to the Clustered Shared Volume
COPY D:\Win8_Gold.vhdx C:\ClusterStorage\Volume1\$VMNAME\C.VHDx
  • Mount the VHD on the parent partition
$mountedvhd = Mount-VHD C:\ClusterStorage\Volume1\$VMNAME\C.VHDx -Passthru -NoDriveLetter
Add-PartitionAccessPath -DiskNumber $mountedvhd.DiskNumber -PartitionNumber 2 -AccessPath C:\VHDMountPoint
  • Inject the Computer Name and IP Address, and “IP of the Provisioning Server” information into the VHDx
ac  C:\VHDMountPoint\Build\computername.txt $VMName
ac  C:\VHDMountPoint\Build\ip.txt $IP
ac  C:\VHDMountPoint\Build\expresssetup1.ps1 'netsh advfirewall firewall add rule name="Temp-InProvisioning" action=allow direction=in profile=All remoteip=$ProvIP'
ac  C:\VHDMountPoint\Build\expresssetup1.ps1 'shutdown -r -t 1'
  • Unmount the VHD
Remove-PartitionAccessPath -DiskNumber $mountedvhd.DiskNumber -PartitionNumber 2 -AccessPath C:\VHDMountPoint
Dismount-VHD -DiskNumber $mountedvhd.DiskNumber
  • Create the VM
$newvm = NEW-VM -Name $VMNAME -Path  C:\ClusterStorage\Volume1\ -VHDPath "C:\ClusterStorage\Volume1\$VMNAME\c.vhdx" -SwitchName "Guest"
Set-VM $newvm -ProcessorCount 4 -DynamicMemory -MemoryMinimumBytes 1GB -MemoryStartupBytes 2GB -MemoryMaximumBytes 8GB
Set-VMNetworkAdapterVlan -VMName $VMName -VlanId 123 -VMNetworkAdapterName "Network Adapter" -Access
Add-ClusterVirtualMachineRole -Cluster MYCLUSTER -VMName $VMName
  • Power on the VM
Invoke-Command -Session $s -ScriptBlock {param ($VMName) Start-VM $vmname } -ArgumentList $VMName
  • Wait a bit of time for the VM to run through it’s autounattend and come online
while (!($(Test-Connection -ComputerName $IP -Count 1 -ErrorAction SilentlyContinue)))
{
sleep 60
Write-Host "Waiting for machine to come online"
}
  • Remotely connect to the VM through WS-MAN and WMI to finish build (domain join, Windows Updates, role/feature installation)
    This part is a bit more complicated and the subject of a later blog post. 🙂

I hope this snippet of PowerShell gets you excited about the flexibility and endless possibilities of setting up your own scripted cloud in Hyper-V with Windows 8.

Good Luck, and Happy Virtualizing!

Janssen

Leave a Reply

Your email address will not be published. Required fields are marked *