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).
[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.
[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.
[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.