In-Depth

Scripting Basics for Virtual Server 2005 R2

Simplify administration of your virtual machines through scripting.

Virtual Server 2005 R2 is an enterprise level application designed by Microsoft to support the simultaneous running of multiple virtual machines on a high performance, scalable, secure and reliable platform. Management can be performed using the Administration Website or writing scripts by taking advantage of the comprehensive Component Object Model (COM)-based Application Programming Interface (API).

As Microsoft enriches more and more products with scripting capability such as PowerShell (code named "Monad") in the highly anticipated Exchange Server 2007, administrators are being empowered to automate routine tasks through scripting instead of having to click through loads of Wizards dialog boxes. Using scripts to automate this rudimentary process ensures high-quality, standard and consistent output. It is with this in mind that we set off to explore the rich programmatic capabilities already available today to simplify the administration of Virtual Server.

Development Environment
In order to develop scripts for Virtual Server, a basic development environment must already exist. Start by downloading and install the free Virtual Server 2005 R2 Enterprise Edition. Whether you're using Windows XP SP2 or Windows Server 2003 as the host development platform, ensure that Internet Information Server (IIS) is already installed. At a minimum, the World Wide Web Publishing service must be running prior to starting the installation process. Microsoft provides support on Windows XP SP2 for non-production use only.

Another Administration Option

In a production environment, IIS can reside on a separate management console to perform remote administration of distributed instances of Virtual Server on different machines through the standard Administration Website. If you're familiar and comfortable with scripting, IIS may not even be necessary. This is because Virtual Server is used as a reference platform for the COM API where virtually all the functionalities are exposed via the Administration Website. Behind the scenes, the VSWebApp.exe is responsible for handling all input/output and interface chores.

VSPlus for Microsoft Virtual Server 2005 is a free tool that can be substituted for the Administration Website shipped with Virtual Server. It comes with both a GUI and command-line version to ease administration.

Because the Virtual Server application programming interface is a standard COM-based object, an administrator has a wide variety of programming and scripting languages to choose from. This ranges from using native or managed code in Visual Basic, Visual Basic Scripting Edition (aka VBScript), Perl, JScript and JavaScript right down to Visual C++/C#. It is even possible to retrofit Virtual Server to run with PowerShell if you are up for the challenge.

To keep things simple without having to delve into the setting up and configuration of a complex development environment, I'll be using the popular VBScript as the scripting language. A significant advantage of using VBScript is that the language itself automatically takes care of essential tasks such as the initialization and marshalling of the COM interface layer.

Scripts developed with VBScript can be executed using the Windows Script Host (WSH) engine shipped with every copy of the operating system since Windows 2000. After testing completes on the development workstation, the scripts can be copied to the destination Virtual Server for local execution. By default, the graphical version of WSH, wscript.exe, will execute against a file with the .VBS extension. It is recommended that you change that to the text-mode version of cscript.exe by issuing cscript //H:CScript at the MS-DOS command line.

The latest version of the WSH should be installed and is downloadable here.

Security
By default, only user accounts that are members of the local machine's Administrators security group have unrestricted access to Virtual Server. This doesn't mean that you should rush out and use local administrative accounts to manage Virtual Server from the Administration Website. As a best practice, it is recommended that you first create a new local security group for this purpose, add relevant user accounts to it and assign only needed permissions to the group. The first two tasks can be easily accomplished using the MS-DOS command line as shown:

net localgroup AdminsVirtualServer
/comment:"Virtual Server Administrators" /add
net localgroup AdminsVirtualServer
adminvserver /add

Next, start the Virtual Server Administration Website and click on "Server Properties" found under "Virtual Server" on the navigation pane. Select "Virtual Server security," push the "Add Entry" button and grant permissions as illustrated. Note that only accounts with appropriate permissions can execute these tasks (typically the local administrator).

Virtual Server Security Properties
[Click on image for larger view.]
Fig. 1: Virtual Server Security Properties

Using this graphical user interface is the preferred and Microsoft-suggested approach to modify permissions for user or group accounts. In the background, Virtual Server updates the discretionary access control list (DACL) on the %ALLUSERSPROFILE%\Application Data\Microsoft\Virtual Server and the default virtual machine configuration folders (and sub-folders). The latter is user-configurable under the "Virtual Server Search Paths" page of the Administration Website and has %ALLUSERSPROFILE%\Documents\Shared Virtual Machines as the default. Obviously, only volumes formatted with NTFS can have DACLs applied.

For the purpose of administrative control via the Administration Website or through the COM interfaces, the "Control" permission must be enabled. Consult Virtual Server's online help for more on this topic.

Why is security important even in scripting, you may ask? Without the proper configuration of permission entry, a script may fail when executed under a security context with insufficient "security clearance." Too much unwarranted security can also lead to the compromise of an entire system. For instance, a script spawns a command shell to delete a VM file, but the "Remove" permission has not been granted. Or a junior administrator is prevented from reading configuration information because the "View" permission is missing hence a VM cannot be scripted to start. You get the picture.

Provisioning
The creation of a new virtual machine with basic configuration settings is described as provisioning. There are four primary building blocks that make up a basic virtual machine, namely processor, memory, network and storage. When building provisioning scripts, some of these devices are automatically created when a virtual machine is born. Other types of device can be individually attached or purposed built, then connected to a virtual machine if not already present.

As a first step in writing scripts to control a virtual machine in a Virtual Server environment, the VirtualServer.Application object must always be initialized:

Set objVS = CreateObject
("VirtualServer.Application")

This defines the top-level application object that connects to the underlying IVMVirtualServer COM interface in the Virtual Server object model. All other Virtual Server interface objects are subsequently exposed through this primary interface.

The next step is to create a virtual machine by utilizing the CreateVirtualMachine method:

Set objVM = objVS.CreateVirtualMachine _
("VistaBuild5384","G:\VMachines")
'name of VM and fully qualified pathname
'vmc file extension automatically tagged

Upon the successful call to this method, a default set of emulated hardware devices is built and attached to the newly created virtual machine in the turn-off state. This is illustrated in Figure 2.

Newly Created Virtual Machine Configuration
[Click on image for larger view.]
Fig. 2: Newly Created Virtual Machine Configuration

Obviously, 64MB of virtual machine memory is all but adequate for legacy guest operating systems such as Windows 9x in today's memory-hungry applications and complex environment. To fix this, allocate the recommended amount of memory by issuing the statement:

objVM.Memory = 384 'in MB

Notice that a virtual disk drive is not listed where it is an absolute necessity to install and run programs on it. This must be separately created with a call to methods that work with virtual storage, such as CreateDynamicVirtualHardDisk or CreateFixedVirtualHardDisk. An example to build a dynamically expanding hard disk image is given here:

Set objVhd =
objVS.CreateDynamicVirtualHardDisk _
("G:\VMachines\VistaBeta2_HDD01", 16000)
'fully qualified pathname of virtual hard disk 'drive, size in megabytes
'vhd file extension added automatically

Although a virtual disk drive can be hooked up as an IDE image to one of the four IDE channels (typically IDE primary channel 0), I recommend SCSI technology to assure optimal performance on Virtual Server.

To commission the previously created fixed disk drive, an extra step must be taken to add a SCSI disk drive controller to the virtual machine. This is achieved with the statements as depicted:

objVhd.WaitForCompletion(100) 'pause for 100 milliseconds for
'task to complete otherwise the VHD
'may not be ready and the
'subsequent statements referencing
'the VHD may fail when called in
'the same script

objVM.AddSCSIController()

Set objVMHardDiskConn =
objVM.AddHardDiskConnection _
("G:\VMachines\VistaBeta2_HDD01.vhd", _
1, 0, 6)
'1=refers to SCSI bus type (0 for IDE) 'of SCSI controller in last statement,
'0=first SCSI bus, 6=SCSI LUN

The last three parameters of AddHardDiskConnection describe the bus type, bus number and device number of the virtual hard disk being connected to the virtual machine. Pay extra attention if a virtual machine were to be shared with Virtual PC that doesn't support SCSI disk drives natively. At this point, the raw virtual disk does not contain any data until it is prepared, just like a regular physical fixed disk.

HRESULT Error Codes

The return value of a call to an object method can either be an object interface, a collection (of objects) or an HRESULT error code. Good programming habits always encourage testing the return value prior to using it in successive statements. Proper error handling is also part of this best practice. To keep this article from going too long, it's not practiced here. Refer to the Virtual Server Programmer's Guide for a list of HRESULT codes.

Finally, one or more virtual DVD-ROM drives should be installed on the new virtual machine. This requires an explicit step that can be achieved with the code fragment below:

set objVMDVDROM = objVM.AddDVDROMDrive(0, 1, 0)
'0=refers to IDE bus type (1 for SCSI)
'1=secondary IDE channel (0 for primary)
'0=channel no. 0 (or channel no. 1)
'DVD-ROM drives not supported on SCSI bus

Networking
Virtual Server maintains a list of virtual networks, each of which simulates a multi-port Ethernet switching hub. Virtual machines communicate freely among themselves when connected to a virtual network. Access to external networks on other subnets will also be possible if configured. During the installation process, a virtual network named "Internal Network" is automatically created by default. In addition, Virtual Server automatically builds a number of other virtual networks, each mapping to an individual physical network adapter found on the host machine. There is no set limit to the quantity of virtual machines that can bond to a particular virtual network. Likewise, you can build as many virtual networks as dictated by your environment.

A single virtual network adapter called "Virtual network adapter 1" is always created and automatically attached to a virtual machine just manufactured. It remains in the "Not Connected" state until patched to one of the available Virtual Server virtual networks by hand or programmatically.

Using the code snippet below, the virtual machine's only network adapter identified as colNICS(1) is linked to the first virtual network. The latter can be referred to by using objVNColl.Item(1), which is turn is normally mapped to the primary physical network adapter found onboard the host machine:

Set objVNColl = objVS.VirtualNetworks
Set collNICs = objVM.NetworkAdapters

collNICs(1).AttachToVirtualNetwork(objVNColl.Item(1))

If a second virtual network exists and is mapped to a physical wireless network adapter, you can connect to it simply by changing objVNColl.Item(1) to objVNColl.Item(2). To retrieve the descriptive name of the hardware adapter, make a call to objVNColl.Item(n).Name, or objVNColl(n).Name.

If the name of the virtual network is already known, one method to attach the virtual network adapter can be coded as such:

Set objVNetwork = objVS.FindVirtualNetwork
("Internal Network")
collNICs(1).AttachToVirtualNetwork(objVNetwork)

For every virtual network adapter attached to a virtual network, Virtual Server will by default assign an Ethernet (MAC) address automatically. This can be overwritten by the user in cases where specific application support needs to be preserved.

To examine the list of available virtual networks in Virtual Server, enumerate the collection with the code snippet here:

Wscript.Echo "Total number of virtual networks=" & _
objVNColl.Count

For i = 1 to objVNColl.Count
WScript.Echo "objVNColl(" & i & ").Item='" & _
objVNColl(i).Name & "'"
Next

Plugging an additional virtual network adapter can be accomplished with a call to the AddNetworkAdapter() method of the virtual machine object. The new adapter will automatically take on the name "Virtual network adapter 2" (default in "Not Connected" state).

Controlling Virtual Machines
Like its physical counterpart, a virtual machine can be turned on or off and undergo a hard reset by pushing the corresponding button. What sets a virtual machine apart from the physical counterpart is that it can be paused, freezing the guest operating system at an exact point in time. Subsequently, you can elect to unfreeze it by choosing the resume option in Virtual Server.

Since no guest operating system yet exists on the newly provisioned virtual machine, the next logical step is to proceed with the installation of a supported operating system. You will first need to instruct Virtual Server to use a physical DVD-ROM media or capture an ISO image. An example using the latter is demonstrated in the following. Executing collDVDs(1).ReleaseImage will release the ISO image.

Set collDVDs = objVM.DVDROMDrives
collDVDs(1).AttachImage
"C:\iso-img\vistabeta2.iso"

At this point in time, you can already power on the virtual machine by running objVM.StartUp() and start interacting with it just like a regular physical machine. To go one step further, let's say that you plan to have a completely hands-free installation experience: You created the unattended installation file "unattend.txt," saved it as "winnt.sif" on a physical floppy disk and captured it as a compatible floppy image. To utilize this image, add the few lines of code below:

Set colFDs = objVM.FloppyDrives
colFDs(1).AttachImage
"C:\iso-img\setupfloppy.vfd"

Make sure that the CD-ROM device is listed as the first bootable device in the virtual machine's BIOS and the floppy image is non bootable. Like the release of an ISO image, run ReleaseImage to free the floppy equivalent.

To manage the state of the virtual machine, you can manipulate it using any of the methods listed:

objVM.Pause 'pause or suspend a virtual machine
'(VM state not saved)
objVM.Resume 'resume a paused virtual machine
objVM.Save 'save VM current state and turn it off
objVM.TurnOff() 'turn off or power off a virtual machine

As a best practice, always free up memory allocated to objects that were created when they're no longer in use. This is accomplished by setting them to Nothing:

Set objVM = Nothing
Set objVhd = Nothing
Set objVS = Nothing

Note that at any time you can check the Event Viewer to discover recent events that have taken place in Virtual Server. This is useful to diagnose and troubleshoot script errors, such as when space ran out when a new virtual machine is being provisioned.

Virtual Server's Event Viewer
[Click on image for larger view.]
Fig. 3: Virtual Server's Event Viewer

Here's a complete listing of the resulting script to provision a virtual machine:

On Error Resume Next

Set objVS = CreateObject
("VirtualServer.Application")

Set objVM = objVS.CreateVirtualMachine
("VistaBuild5384a","G:\VMachines")
'name of VM and fully qualified pathname
'vmc file extension automatically tagged

objVM.Memory = 384 'in MB

Set objVhd =
objVS.CreateDynamicVirtualHardDisk _
("G:\VMachines\VistaBeta2_HDD01", 16000)
'fully qualified pathname of virtual hard disk 'drive, size in megabytes
'vhd file extension added automatically

objVhd.WaitForCompletion(100) 'wait for 100 milliseconds for
'task to complete otherwise the VHD
'may not be ready and the
'subsequent statements referencing
'the VHD may fail when called in
'the same script

objVM.AddSCSIController()

Set objVMHardDiskConn = objVM.AddHardDiskConnection
("G:\VMachines\VistaBeta2_HDD01.vhd", 1, 0, 6)
'1=refers to SCSI bus type (0 for IDE) 'of SCSI controller in last statement,
'0=first SCSI bus, 6=SCSI LUN

set objVMDVDROM = objVM.AddDVDROMDrive(0, 1, 0)
'0=refers to IDE bus type (1 for SCSI)
'1=secondary IDE channel (0 for primary)
'0=channel no. 0 (or channel no. 1)
'DVD-ROM drives not supported on SCSI bus

Set objVNColl = objVS.VirtualNetworks
Set collNICs = objVM.NetworkAdapters

collNICs(1).AttachToVirtualNetwork
(objVNColl.Item(1))

Set collDVDs = objVM.DVDROMDrives
collDVDs(1).AttachImage
"C:\iso-img\vistabeta2.iso"

Set colFDs = objVM.FloppyDrives
colFDs(1).AttachImage
"C:\iso-img\setupfloppy.vfd"

objVM.StartUp()

Set objVM = Nothing
Set objVhd = Nothing
Set objVS = Nothing

More Resources

For more on scripting for Virtual Server, check out the following materials and links:

* Both are installed by default as part of Virtual Server setup.

Summary
So we've walked through on how to build an environment to support Virtual Server script development with readily available tools and resources. We've covered the basics of scripting COM objects in Virtual Server from provisioning, configuring and general operations of virtual machines. This, however, is only the tip of the iceberg of what scripting can do for you.

comments powered by Disqus

SharePoint Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.