Alex Mueller on Software and Technology 
Wednesday, March 25, 2009

I am always looking for tools to allow me to do more by doing less. Administering Hyper-V with PowerShell can be tedious. James O’Neill’s PowerShell Management Library for Hyper-V is a great tool to improve automation of Hyper-V management using PowerShell.

As a tester, I am constantly creating new environments, installing our product, taking snapshots, ect. Doing this by hand is a waste of time in my opinion. Doing this with a script makes life easier and frees up my time.

Typically, I prefer to create is to create one VM and to have other VMs inherit from that base image. My second VM (the first child to inherit from the base), I will install daily builds of our product. I will then create a third child, which I use a sandbox. I can easily delete it and recreate as needed without having to install our product over again. I have not consistently found success with using snapshots, so I prefer to use differencing disks. The examples below use differencing disks.

This first code block shows how I am using the PowerShell management library to simply the creation of a base VM. There is nothing magic about it. It’s pretty strait-forward. I create a VM, give it a name, set the CPU count, memory size, network adapters, hard drive, and DVD drive.

$server = "my-dev-server"
$vmName = "TestParentVM"
$vmVirtualSwitch = "My Virtual Network"

# create a new virtual machine
$vm = New-VM $vmName -server $server

# set cpu count
Set-VMCPUCount $vm 2 -server $server

# set memory size
Set-VMMemory $vm 2 -memory 4GB -server $server

# add a legacy network adapter
Add-VMNIC -vm $vm -VirtualSwitch $vmVirtualSwitch -legacy

# add a default VMBus (non-legacy) network adapter
Add-VMNIC -vm $vm -VirtualSwitch $vmVirtualSwitch

# add the hard drive to the VM
Add-VMNewHardDisk –vm $vm -controllerID 0 -lun 0 -vhdpath "$(get-VHDdefaultPath)\$vmName.vhd" -size 20GB

# add the DVD with bootup ISO
Add-VMDRIVE –vm $vm 1 1 -server $server -DVD 

Write-Host "Operation complete."

The next code block will create a differencing disk pointing to the parent created in the previous example. I create the usual, VM, CPU count, ect. What makes this a differencing disk is how the VHD is created by specifying the parent. I do some cleanup in this routine by deleting any previously created VMs or VHDs, and I loop through the creation a failure preventative.

$server = "my-dev-server"
$vmName = "TestChildVM"
$vmParent = "TestParentVM"
$vmVirtualSwitch = "My Virtual Network"

#region functions - feel free to move to a separate file

Function DeleteVhd
{
    Param ($pathToVhd)
    # delete the disk that was added if it exists
    if (test-path -path $pathToVhd)
    {
        Remove-Item -Path $pathToVhd -Force
    }
}

#endregion

# delete the VHD if it already exists
DeleteVhd "$(get-VHDdefaultPath)\$vmName.vhd"

# delete the VM if it already exists
Remove-VM -vm $vmName -server $server

# create a new virtual machine
$vm = New-VM $vmName -server $server

# get the vm
$vm = Get-VM $vmName

# set cpu count
Set-VMCPUCount $vm 2 -server $server

# set memory size
Set-VMMemory $vm 2 -memory 4GB -server $server

# get VM Nics available
$vmNics = Get-VMNic -server $server -vmbus -legacy
$vmNicSwitchList = New-Object System.Collections.ArrayList

# get VM Nic Switch available for each VM Nic and add it to our list
foreach ($vmNic in $vmNics)
{
    $vmSwitchElementName = (Get-VMNicSwitch $vmNic).ElementName
    if ($vmNicSwitchList.Contains($vmSwitchElementName) -ne $true)
    {
        $vmNicSwitchList.Add($vmSwitchElementName)
    }
}

# Use the first available VM Nic Switch - this assumes 
# I do not create more than on per each environment.
if ($vmNicSwitchList.Count -gt 0)
{
    $vmVirtualSwitch = $vmNicSwitchList[0]
}

# add a legacy network adapter
Add-VMNIC -vm $vm -VirtualSwitch $vmVirtualSwitch -legacy

# add a default VMBus (non-legacy) network adapter
Add-VMNIC -vm $vm -VirtualSwitch $vmVirtualSwitch

# add the hard drive to the VM
$parent = "$(get-VHDdefaultPath)\$vmParent.vhd"
$vhdPath = "$(get-VHDdefaultPath)\$vmName.vhd"
Add-VMNewHardDisk –vm $vm -controllerID 0 -lun 0 -vhdpath $vhdPath -parent $parent

# get the VM to see if a disk is attached to it, if it is not, then it failed
$disks = Get-VMDisk -vm $vm
$count = 1

# if the disk was not successfully added, try and add it again
while ($disks -eq $null -and $count -le 5)
{
    Write-Host "RETRY $count - The disk was not properly added. Attempting to retry."
    
    # delete the disk that was added
    DeleteVhd "$(get-VHDdefaultPath)\$vmName.vhd"
    
    Add-VMNewHardDisk –vm $vm -controllerID 0 -lun 0 -vhdpath $vhdPath -parent $parent
    
    $disks = Get-VMDisk -vm $vm
    $count++
}

if ($disks -eq $null)
{
    Write-Host "Operation failed to create this virtual machine. Contact an admin."
}
else
{
    Write-Host "Operation completed successfully. Attempting to start the VM."
    Start-VM -vm $vm -wait
}

I have found that the VM creation is not consistently successful on the first pass, so I have added the while loop. Since adding that, I have not had any issues.

I hope these help. They should be easy to change if you prefer snapshots versus differencing disks. Thanks to James O’Neill for creating this library. It makes administering Hyper-V much easier. It is available via CodePlex, where the latest release, updates, and forum support can be found.

Wednesday, March 25, 2009 2:44:50 PM (Mountain Standard Time, UTC-07:00) | Comments [1] | PowerShell | Tools#
MuellerDesigns.net
Search
On This Page
The Split Personality of the Tester/Developer
Cross Site Scripting (XSS)
Creating files with FSUTIL
PowerShell Management Library for Hyper-V
Installing Windows 7
Installing Linux in Hyper-V
Internet Explorer 8 Release Candidate 1
PowerShell Documentation
Automate Daily Tasks with PowerShell
SketchPath XPath Editor
Software Testing - Revisited
Architecting Buildings and Software
NBCOlympics.com with Silverlight
Marker Interfaces and C# Attributes
Most Popular
JavaScript ReplaceAll Functionality
What is polymorphism?
What is composition?
Sorting with IComparable and IComparer
Applying the Observer Pattern in ASP.NET
MVP in ASP.NET
What is abstraction?
What is encapsulation?
What is a class?
What is inheritance?
Authentication in ASP.NET
Calendar Controls
XPathNavigator.CheckValidity new for 2.0
SQL Server 2005 Connection Issues
Auto-attach to process '[####] aspnet_wp.exe' on m...
What is an object?
FreeTextBox
VMWare and VPC
An Example of Reflection using C#
Changing File Ownership In Vista and Longhorn
Archive
Links
Categories
My Local Blog Map
Blogroll
About
Powered by:

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
MuellerDesigns.net

Sign In

Help Those In Need
The Hunger Site
Ronald McDonald House Charities (RMHC) of Western Washington & Alaska