Scripting School

Getting started with Windows PowerShell and Microsoft Hyper-V

We've talked in previous columns about how to use Windows PowerShell to manage some aspects of presentation virtualization done with Microsoft Terminal Services, but you can use PowerShell to manage other virtualization technology, too. Hyper-V, the machine virtualization technology from Microsoft, can also be managed from the command line.

With Windows PowerShell, it's possible to do common tasks such as:

  • finding a virtual machine (VM) or VM Host
  • connecting to a VM
  • starting, stopping, or suspending VMs
  • backing up, exporting, and snapshotting VMs
  • creating and deleting VMs (including memory and CPU settings)
  • working with disk controllers, drives, and disk images
  • configuring VM network connections

There are two ways to manipulate Hyper-V from PowerShell. One way is to use Hyper-V's Windows Management Instrumentation (WMI) provider. This method is fully tested and part of Windows Server 2008, so it's supported. On the other hand, it means using WMI, which while less painful through PowerShell than other means, can still be challenging at times.

The other option is to use the

    Requires Free Membership to View

PowerShell Management Library for Hyper –V from CodePlex. This resource is not fully tested or part of Windows Server 2008. It also may not include identical functionality to the Hyper-V WMI and is not supported, so you may not want to use it on production servers. It is simpler, however, since the developer has created cmdlets for a lot of the tasks you'll want to do. Since the developer of this library has gone to the trouble of putting a pretty face on key tasks, it's worth exploring.

Just to set the stage, let's see how you'd use WMI and the PowerShell Management Library for Hyper-V to create a new VM. We'll explore more complex tasks later, but this one will help clarify how the basics of virtual machine management work.

Creating a new virtual machine with WMI

Creating a new virtual machine with WMI requires two basic steps:

  1. Populate the contents of a set of data stored in an instance of the CIM_VirtualSystemSettingData class, called SystemSettingData

  2. Feed the data in SystemSettingData to the DefineVirtualSystem method

If you want to use the default settings to populate SystemSettingData, you can create a VM like this:

$VSM = get-wmiobject -namespace\rootvirtualization
Msvm_VirtualSystemManagementService

$newVM = $VSM.DefineVirtualSystem()

Want more discretion over the VM settings? Read on. The two basic steps don't change but your involvement does. The following example creates a VM with a customized storage location, name and description.

First, you need to create an instance of the MsVM_VirtualSystemGlobalSettingData class, which is derived from CIM_VirtualSystemSettingData. You can't just make an instance of CIM_VirtualSystemSettingData because that's the parent class from which the WMI class is derived. To make it easier to work with, we'll assign this class the variable name VSG (for Virtual System Global).

$VSG=([wmiclass]"\\$HyperVServer\root\virtualization:MSVM_
VirtualSystemGlobalSettingData").
createInstance()

Next, we need to edit the raw data for this class. To get to the base object directly, tell PowerShell that you want the base object by affixing .psbase to the WMI class, like this:

$VSG.psbase

Note: Although you can skip that step and still create the virtual machine, PowerShell will show an error if you don't connect to the base object before you start populating the VM properties.

Now you've got a grip on the base object and can populate its properties to define data about the VM. The VM's properties are stored in $VSG.psbase.Properties. To populate them, you'll need the Item method  to give you access to the property object. Once you have this access, you can populate the properties by referring to them by name. To create this custom virtual machine, you need to tell the Hyper-V service where to put the VM (stored as ExternalDataRoot), what to call the VM (stored as ElementName) and the description for the VM (stored as Description).

$VSG.psbase.Properties.Item("ExternalDataRoot").value = $VMLocationPath

$VSG.psbase.Properties.Item("ElementName").value = $VMName

$VSG.psbase.Properties.Item("Description").value = $VMDescription

Now it's time for a quick sideline that won't actually appear in your script. As you can see, this step assumes a bit of knowledge. How did you know the name of the VM needed to be stored in the ElementName property? What's an external data root? The most accurate (and fastest, since you're scripting) way of determining what properties are available to you for a class is to use PowerShell to document the class for you. This is very simple:

$vsg.psbase.properties

This command tells PowerShell to get all the information about the childitems in psbase.properties and display the output in the command window. Run this command, and you'll get an output that looks like this snippet.

Name : ExternalDataRoot
Value :
Type : String
IsLocal : False
IsArray : False
Origin : Msvm_VirtualSystemGlobalSettingData
Qualifiers : {CIMTYPE}

Basically, this output is saying that the name of this property is ExternalDataRoot, it doesn't have a default value, the data is stored as a string, it's part of the Msvm_VirtualSystemGlobalSettingData class (that IsLocal is False means that this property is derived from another class, not defined in this one), it's a single value, and it's a CIM property. If the documentation isn't completely clear, put the Name into your favorite online search engine and look at the documentation on MSDN for a fuller description of that property.

Where'd the script get the values to fill those properties? You can provide them as arguments or, especially in the case of properties such as ExternalDataRoot which you'll to want to be consistent, you can hardcode them into the script like this:

$HyperVServer = "Everest"

$VMName = "testVM"

$VMLocationPath = "C:\TESTVHD1"

$VMDescription = "VM created using PowerShell"

Creating a new virtual machine with the Library

After all this effort, creating a new VM with the CodePlex library is very simple. To create a new virtual machine with a specified name in the default location, run this cmdlet:

new-vm TESTVM

By default, this cmdlet will create a VM on the local server. To specify the server on which you want to create the VM, you'll need to use the –name and –server parameters. The following example creates the VM "TestVM" on the server "BIGSERVER":

new-vm –name TESTVM –server BIGSERVER

This is much easier than the WMI method, but there are a few things to notice about New-VM:

  • You can't specify the storage path
  • You can't add a description
  • You can't edit any of the other VM properties that you saw when you did a dir on $vsg.psbase.properties, as in the previous section.

The New-VM cmdlet approach is fast and easy, but WMI gives you more control. To edit virtual machine settings to an existing VM, you'd need a second library cmdlet: Set-VM, which we will discuss in a later column.

Virtualization as a technology is becoming increasingly important. Managing the VMs on your Hyper-V servers will be a lot simpler if you have the scripts ready to do it. While PowerShell is not supported on Windows Server 2008 Core (there is a way to install it, but it's not supported), it will be supported on Core in Windows Server 2008 R2.

This column should get you started working with Windows PowerShell and Hyper-V. We'll continue in this vein in future columns.

Miss a column? Check out the Scripting School archive.

Christa Anderson, a former Terminal Services MVP, is a program manager on the Terminal Services team at Microsoft and author of the forthcoming Windows Terminal Services Resource Kit from Microsoft Press. She is an internationally known authority on scripting, the author of Windows Terminal Services, The Definitive Guide to MetaFrame XP, and co-author of the book Mastering Windows 2003 Server.

Kristin Griffin is an independent consultant and author with more than 10 years of experience in creating and maintaining Microsoft-centric networks using scripting to automate tasks and reduce errors from manually performed system administration. She recently co-authored Windows Server 2008 Terminal Services Resource Kit (Microsoft Press, 2008) and is a contributor to Mark Minasi's Mastering Windows Server 2008: Enterprise Technologies.


This was first published in May 2009

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to: