Dung K Hoang 的个人资料Dung's space日志网络 工具 帮助

日志


5月9日

Hyper-V WMI Examples - Part VIII

 

Adding Resources of a VM

To continue from the previous post, let's discuss how you can add a resource to a VM. In this scenario, I want to add a new DVD drive to my VM virtual machine and attach an ISO file called c:\ISO\W2K3.ISO.

When you explore settings of a given VM using the Hyper-V Manager console, you notice that a VM can have up to 2 IDE controllers (0,1) and each IDE controller has 2 slots (0,1). You can add either a disk drive or a DVD drive to each of the IDE controllers.

You also notice that you can only add a drive (disk or DVD) when selecting a controller and cannot use the generic action "Add Hardware" to add a drive. The script should behave exactly like the GUI interface, meaning that I have to provide the IDE controller number and slot as parameters when creating a drive.

Enough talk , let's do real work :=)

Note:  Script updated based on James Logan's feedback.

Assume that I want to add a DVD drive to my VM on IDE Controller 1 at location 1

-------------------Start of Script to Add a resource ------------------------------------------------

VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$VM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "My VM"}

# Step 1; Locate an IDE controller and an available location 

$ListOfControllers = get-wmiobject -namespace root\virtualization Msvm_ResourceAllocationSettingData | `
                          where {$_.ResourceSubType -like "*Emulated*IDE*"}

foreach ($Controller in ListOfControllers)
{

            if ($Controller.Address -eq 1)
            {
             # It must return exactly one controller. Let's assume that is the case
             $IDEController1 = $Controller
             }
}

# Step 2: Create a synthetic DVD drive
# Now we create a new DVD drive. To create a new drive you will search for the Default instance object and clone it.

$DVD_Default = get-wmiobject -namespace root\virtualization Msvm_ResourceAllocationSettingData | `
                          where {($_.ResourceSubType -like "Microsoft Synthetic DVD Drive") -and ($_.InstanceID -like '*Default*'" )}  

$NewDVDDrive = $DVD_Default.psbase.Clone()

## So fill out the necessary information

$NewDVDDrive.Parent = $IDEController1.__PATH

$NewDVDDrive.Address = 1              

## Apply the changes

$VM_Service.AddVirtualSystemResources($VM.__PATH, $NewDVDDrive.psbase.Gettext(1))

  #Step 3: Create a CD/DVD disk

# First locate the new DVD drive created in previous step.
# Note: There must be a more elegant way to find a DVD drive attached to IDE controller 1 at location1.
#          I just use a quick and "dirty" way to get it.

$NewDVD = get-wmiobject -namespace root\virtualization Msvm_ResourceAllocationSettingData | `
                          where {($_.ResourceSubType -like "Microsoft Synthetic DVD Drive") -and ($_.InstanceID -like '*\1\1\*'" )}  

# Create a CD/DVD disk. To create a new disk you will search for the Default instance object and clone it.

$CD_Default = get-wmiobject -namespace root\virtualization Msvm_ResourceAllocationSettingData | `
                          where {($_.ResourceSubType -like "Microsoft Virtual CD/DVD Disk") -and ($_.InstanceID -like '*Default*'" )}  

$CDDisk = $CD_Default.psbase.Clone()
$CDDisk.Parent = $NewDVD.__PATH
$CDDisk.Connection = "c:\ISO\W2K3.ISO"

# Apply the changes
$VM_Service.AddVirtualSystemResources($VM.__PATH, $CDDisk.psbase.Gettext(1))

-------------------End of Script to Add a resource ----------------------------------------------

Done!

Until the next time ......

/Dung

 HyperV WMI PowerShell

Hyper-V WMI Examples - Part VII

 

Modifying Resources of a VM

Now that you know how to query WMI to get list of resources associated to a VM, let's discuss how you can modify a resource.

Modifying the location of VHD file

Let's say that my VM has a VHD file named C:\VMs\MyVM.VHD and I want to move the location of the file from C: to L: drive. After copying the VHD file to the new location, here is the script to change the location of the disk image file for the VM

-------------------Start of Script to modify a resource ------------------------------------------------

VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$VM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "My VM"}

## First you need to locate the active settings of a virtual machine
$VMSettingData = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData -filter "SystemName = `'$($VM.Name)`'"

## Then find all the resources allocated to this VM.
## Here we are interested only on Msvm_ResourceAllocationSettingData instances.
$VResourceComponents = gwmi -namespace root\virtualization Msvm_VirtualSystemSettingDataComponent | `
                                       where {($_.GroupComponent -like $($VMSettingData.__PATH)) -and ($_.PartComponent -like `
                                      "*Msvm_ResourceAllocationSettingData*")} 

## IN this scenario, I'm interested only on the resources whose Subtype is "Microsoft Virtual Hard Disk "

foreach ($item in $VResourceComponents)

{

# Get a WMI instance from the path stored in the PartComponent Property

$VRes= [WMI]$item.PartComponent

if ( $VRes.ResourceSubType -eq "Microsoft Virtual Hard Disk")

       { $Res_VHD = $VRes }

}

if ($Res_VHD -ne $NULL)

         {

           $Res_VHD.Connection = $Res_VHD.Connection -replace "C:", "L:"

$VM_Service.ModifyVirtualSystemResources ($VM.__PATH, $Res_VHD.psbase.Gettext(1))

}

-------------------End of Script to modify a resource ------------------------------------------------

 

Enjoy!

/Dung

 HyperV WMI PowerShell

5月4日

Hyper-V WMI Examples - Part VI

 

Today I will talk about finding resources of virtual machine.
A resource associated to a virtual machine includes virtual hard disk, NIC, DVD drive... and each resource is represented by an instance of a class Msvm_ResourceAllocationSettingData. This class has some interesting properties:

  • Resource Type: a value indicating the generic type of resource such as: CPU, Memory, IDE Controller, Parallel SCSI HBA, FC SCSI HBA, iSCSI HBA, FCP Adapter, IB HCA, Ethernet Adapter, Other Network Adapter, I/O Slot, I/O Device, Floppy Drive, CD/DVD drive, Serial port, Parallel port, USB Controller, Graphics controller, Disk, Tape, Other storage device, Firewire Controller
  • Resource SubType: a string that describes a specific implementation of the resource. For example, a disk drive in Hyper-V has a ResourceSubType of "Microsoft Disk Drive" which is MS implementation of the resource of type Disk.
  • Connection: This is a link of the object to the "real" resource. For example, a hard disk drive of a VM that points to a VHD file has the Connection string set to the path of the VHD file.

 

Now that you understand how a resource is represented in Hyper-V, the next question is how those resources are attached to a specific Virtual Machine (VM). First all virtualization-specific settings of each VM is represented by an instance of the class Msvm_VirtualSystemSettingData.  The class describes a kind of "motherboard" of a VM. It has properties like BIOS, BaseBoardSerialNumber... Do note that a snapshot is also represented by an instance of the same class, it means that a snapshot is also viewed as a virtual machine of a specific type.

Once you get the Msvm_VirtualSystemSettingData, you can find all resources associated to a VM by querying the class Msvm_VirtualSystemSettingDataComponent. The query returns all associations between an instance of  Msvm_VirtualSystemSettingData and one or more instances of Msvm_ResourceAllocationSettingData.

This is how you can find resources that are allocated to a VM. You need to go through Msvm_VirtualSystemSettingData and then Msvm_VirtualSystemSettingDataComponet 

So let's put it in practice:

$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$VM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "My VM"}

## First you need to locate the active settings of a virtual machine
$VMSettingData = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData -filter "SystemName = `'$($VM.Name)`'"

## Then find all the resources allocated to this VM.
## Here we are interested only on Msvm_ResourceAllocationSettingData instances.
$VResourceComponents = gwmi -namespace root\virtualization Msvm_VirtualSystemSettingDataComponent | `
                                       where {($_.GroupComponent -like $($VMSettingData.__PATH)) -and ($_.PartComponent -like `
                                      "*Msvm_ResourceAllocationSettingData*")} 

## Now we have all resources associated to a VM, let's enumerate them

foreach ($item in $VResourceComponents)

{

# Get a WMI instance from the path stored in the PartComponent Property

$VRes= [WMI]$item.PartComponent

write-host "Type is $($VRes.ResourceType), SubType is $($VRes.ResourceSubType), Connection is $($VRes.Connection) "

}

Et Voilà!

/Dung

 HyperV WMI PowerShell

4月24日

Hyper-V WMI Examples - Part V

 

Managing virtual machines (con' td)


Sometimes you need to create a new virtual machine, modify some configuration settings like the amount of virtual memory, the location of the VHD file... Also you may want to know how to rename the snapshots with a more friendly name.

Let's see how you can do it with scripts

1. Create a new virtual machine

Updates for RC1

Withe the Hyper- RC1 release, it is very simple to create a new virtual machine.. You simply call the method DefineVirtualSystem. Here is an example:

----------------------Create new empty VM -------------------------------------------

$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$newVM = $VM_Service.DefineVirtualSystem()

----------------------End-of-script --Create new empty VM -------------------------------------------

 

2. Change DisplayName

Once the new virtual machine is created, its display name is set to a default value of "New Virtual Machine". If you want to change the display name to a different value, you can do the following:

----------------------Change Display Name of VM -------------------------------------------$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$NewVM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "New Virtual Machine"}
$VMSettingData = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData -filter "SystemName = `'$($NewVM.Name)`'"
$VMSettingData.ElementName = "W2K8FULL01"       
$VM_Service.ModifyVirtualSystem($NewVM.__PATH, $VMSettingData.psbase.getText(1))

----------------------End-of-script --Change Display Name of  VM -------------------------------------------

 
2. Configuring virtual memory

Now you want to add more virtual memory to the new VM by increasing its RAM from 512MB to 1GB. You need to look at the class Msvm_MemorySettingData whose one of the properties contains the actual value of virtual memory allocated to a VM.
Here is an example of script:

----------------------Change Virtual Memory of VM -------------------------------------------$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$NewVM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "New Virtual Machine"}

## First you need to locate the active settings of a virtual machine
$NewVM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "New Virtual Machine"}
$VMSettingData = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData -filter "SystemName = `'$($NewVM.Name)`'"

## Then find all the resources allocated to this VM. One particular resource is the Virtual Memory resource
$Vmem = gwmi -namespace root\virtualization Msvm_VirtualSystemSettingDataComponent | where {$_.PartComponent -like "*memory*"}

## Find an instance of Msvm_MemorySettingData that matches with $VMem.PartComponent
$Mem =  gwmi -namespace root\virtualization Msvm_MemorySettingData | where {$_.__PATH -like $($Vmem.PartComponent) }

## Now modify the quantity of RAM
$Mem.VirtualQuantity = [string]1024
$Mem.Reservation = [string]1024
$Mem.Limit = [string]1024

## Commit Changes
$VM_Service.ModifyVirtualSystemResources($NewVM.__PATH, $Mem.psbase.getText(1))

------------------End-of-script----Change Virtual Memory of VM -------------------------------------------

 

3.  Rename a snapshot

The script is similar to the one that changes the display name of the VM. Indeed, we need to identify an instance of the Msvm_VirtualSsytemSettingData class that represents a snapshot (SettingType =5 is the trick!)

Here is an example:

----------------------Rename a snapshot -------------------------------------------

$VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$NewVM = gwmi -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like "New Virtual Machine"}

## Find snapshot associated to this machine - Assume you have only one
$LastSnapShot = get-wmiobject -namespace root\virtualization -class Msvm_VirtualSystemSettingData -filter “SystemName=`'$($NewVM.Name)`' and SettingType = 5”
$LastSnapShot.ElementName = "Snapshot taken yesterday before installing Exchange"

## Commit changes
$VM_Service.ModifyVirtualSystem($NewVM.__PATH, $LastSnapShot.psbase.getText(1))

----------------------End-of-script -------- Rename a snapshot -------------------------------------------


Hope you find those samples useful!

Enjoy!

/Dung

 HyperV WMI PowerShell

4月21日

Hyper-V WMI Examples - Part IV

 

Managing virtual machines


During our training event, I'm constantly asked to find a way to stop or pause VMs that students have launched during the lecture session. As students are using their clients to view the powerpoint slides, we cannot TS directly to the server and manually stop/pause the VMs. Also we have up to 600 VMs to manage, so locating the running VMs is not a simple task.

Also at the end of the day, I'd like to take snapshots of all running VMs

So I decide to use Hyper-V WMI API to write a script for changing states of VMs. In the following examples, our host systems are named HVHOSTXX where xx starts from 02 to 15.

-------------------Script to pause all VMs ------------------------------------------------

##
##    Create VM State table
##

$State     =     @{‘Enabled’ = 2 ; ‘Disabled’= 3;  ‘Paused’= 32768 ; ‘Suspended’ = 32769 ; ‘Starting’ = 32770 ; ‘Snapshotting’ = 32771 ;  `
         ‘Migrating’ = 32772 ; ‘Saving’ = 32773 ; ‘Stopping’ = 32774 ; ‘Deleted’ = 32775 ; ‘Pausing’ = 32776 }

2..15 | % {

$server = "HVHOST{0:D2}" -f $_
$VM_Service = get-wmiobject -computername $server -namespace root\virtualization Msvm_VirtualSystemManagementService
$ListofVMs =get-wmiobject -computername $server -namespace root\virtualization Msvm_ComputerSystem -filter  "ElementName <> Name " 

foreach ($VM in $ListOfVMs)
{
    write-host -foreground yellow "Saving state VM $($VM.ElementName) now"
    $VM.RequestStateChange($State['Suspended'])
}

}

---------------------------------- End of Script ---------------------------------------------------

-------------------Script to take snapshots of all VMs ------------------------------------------------

2..15 | % {

$server = "HVHOST{0:D2}" -f $_
$VM_Service = get-wmiobject -computername $server -namespace root\virtualization Msvm_VirtualSystemManagementService
$ListofVMs =get-wmiobject -computername $server -namespace root\virtualization Msvm_ComputerSystem -filter  "ElementName <> Name "  

foreach ($VM in $ListOfVMs)
{
    write-host -foreground yellow "Snapshotting VM $($VM.ElementName) now"
    $VM_service.CreateVirtualSystemSnapShot($VM.__PATH)
}

}

## 600 VMs being snapshotted in one go!

---------------------------------- End of Script ---------------------------------------------------

 

Quite easy, hey?

/Dung

HyperV WMI PowerShell

Hyper-V WMI Examples - Part III

 

Exporting and Importing virtual machines


Hello All,

I was so swamped in preparing an internal training on WS08 for our folks and was not writing any post since a while.
Anyway, I just want to let you know that 2 weeks ago, we have deployed the "largest" Hyper-V systems including 600 VMs running on 15 Blade Servers. All virtual machines VHD files are stored on a SAN (EVA 4000) of 5.3 TB of data.

All this deployment can't be done without scripts to automate the operation. I'm pleasantly surprised with the Hyper-V WMI API that allow us to do most of the deployment work and I will share those scripting experiences with you.

FYI, here is the process we put in place to deploy virtual machines:
1. Create a master set of Virtual machines
2. Export those VMs
3. Copy all the export files and VHDs to each physical host system
4. Create virtual networks
5. Import virtual machines
5. Create AzMan Scope to restrict access to VMs per student


Let's discuss today about exporting/importing virtual machines.

Exporting virtual machine

Unlike VS 2005, when you want to move a virtual machine from one host to another, you cannot simply copy the configuration file (.VMC) and the VHD file and "make it "appear on the destination host with Hyper-V. To perform the same operation, you need to export the VM from the source host system, copy all the export files to the destination host and then import it into Hyper-V.

When exporting a VM, you can either export only configuration files (that contains all settings for this VM) or include all save state files (.vsv files), snapshot files (.AVHD files) and VM binary (.VHD file).

After you specify a root folder to store export files, the export operation will create a folder structure for you under the root folder as follow: ( assuming that the root folder is called C:\Export)

C:\Export

    |---------- <VM_Name>

         | ----------------  Virtual Machines       

         | ---------------- Virtual Hard Disks

The Virtual Machines sub-folder contains an export file (.EXP) that Hyper-V creates for export and eventually VSV files and AVHD files if you specify the option to export save state files for export. The EXP file will be read by the import operation to re-create settings for virtual machine at destination.

The Virtual Hard Disks sub-folder is the location where VHD file will reside.

To script the export operation with Hyper-V WMI, you simply call the method of the Msvm_VirtualSystemManagementService Class and specify a reference to the VM to be exported, a flag that indicates whether you want to export system state files or not and an export folder. The call returns either 0 or 4096. All other values indicate an error in the parameters passed to the call.
If it returns 0, it means that the method is executed synchronously, If it returns 4096, the method is executed asynchronously and the Job output parameter can be used to track progress of the operation.

Here is an example:

## Get reference to a VM to be exported
PS C:\> $Core = get-wmiobject -namespace root\virtualization -class Msvm_ComputerSystem -filter " ElementName = 'IIS-CORE' "

## Connect to the Virtual machine Management Service
PS C:\> $VM_Service = get-wmiobject –namespace root\virtualization –class Msvm_VirtualSystemManagementService

## call the Export method
PS C:\> $status = $VM_Service.ExportVirtualSystem($Core.__PATH, $True, "C:\Export")
PS C:\> If ($Status.ReturnValue -eq 0) { write-host "Operation Sucessful"; exit}
PS C:\> if ( $status.ReturnValue -eq 4096) { $JobStatus = $Status.Job.JobState; while ($JobStatus -ne 0) { sleep(1) } }

Importing virtual machines

The next step is to copy the folder structure under C:\Export to the destination host. It is not recommended to import a VM directly from the export folder and the import operation does not support network drive or network share folder so you can't simply point the import operation to a network share like \\Server\C$\Export.

Here is an example of scripting the import operation:

## Connect to the Virtual machine Management Service
PS C:\> $VM_Service = get-wmiobject –namespace root\virtualization –class Msvm_VirtualSystemManagementService

## call the Import method
PS C:\> $FlagGenerateNewID = $True # To ensure that the new imported VM will always get a new ID (GUID)
PS C:\> $status = $VM_Service.ImportVirtualSystem("C:\VMs\IIS-CORE", $FlagGenerateNewID)
PS C:\> If ($Status.ReturnValue -eq 0) { write-host "Operation Sucessful"; exit}
PS C:\> if ( $status.ReturnValue -eq 4096) { $JobStatus = $Status.Job.JobState; while ($JobStatus -ne 0) { sleep(1) } }

 

Bulk Export and Import

If you have a set of virtual machines to be exported from one machine and then to be imported on a different host, you can automate the operation as follow:

On the Source Server

$VM_Service = get-wmiobject -computer $SourceServer –namespace root\virtualization –class Msvm_VirtualSystemManagementService

$ListofVMs = get-wmiobject -computer $SourceServer -namespace root\virtualization -class Msvm_ComputerSystem -filter " ElementName <>Name"

foreach ($VM in $ListofVMs)
{

$status = $VM_Service.ExportVirtualSystem($VM.__PATH, $True, "C:\Export")
If ($Status.ReturnValue -eq 0) { write-host "Operation Sucessful"; exit}
if ( $status.ReturnValue -eq 4096) { $JobStatus = $Status.Job.JobState; while ($JobStatus -ne 0) { sleep(1) } }

}

robocopy /z /s C:\Export \\$DestServer\C$\VMs

On the Destination Server

$VM_Service = get-wmiobject -computer $DestServer –namespace root\virtualization –class Msvm_VirtualSystemManagementService

$ListOfFolders =  dir "C:\VMs" | where { $_.PSIsContainer} | select FullName
foreach ($f in $ListOfFolders)
{
    $Folder = $f.FullName
    $Status  = $VM_Service.ImportVirtualSystem($Folder,$True)
    If ($Status.ReturnValue -eq 0) { write-host "Operation Sucessful"; exit}
    if ( $status.ReturnValue -eq 4096) { $JobStatus = $Status.Job.JobState; while ($JobStatus -ne 0) { sleep(1) } }

}

Until next time....

/Dung

 

HyperV WMI PowerShell

2月7日

Hyper-V WMI documentation not complete yet

 

I just find out that some WMI calls are not documented in the MSDN library for Hyper-V. Apparently there are three methods in MSvm_VirtualSystemManagementService to create a new virtual machine and only one of them is explained.

    • DefineVirtualSystem : Method used to create a computer system
    • PlanVirtualSystem
    • InstantiateVirtualSystem

I know that the documentation is still in early beta phase and appreciate all effort of Microsoft for publishing it. Even with the current state of the materials, there is a lot of things you can do with WMI against Hyper-V

So Enjoy!

/Dung

2月5日

Hyper-V WMI Examples - Part II

 

The Msvm_VirtualSystemManagementService Class

Today I discuss about the Msvm_VirtualSystemManagementService Class. The Msvm_VirtualSystemManagementService class represents the virtualization service running on the host system. Using this class, you can control the creation, modification, deletion, import and export of virtual systems. You can also create snapshots and apply them to virtual systems. All those operations are exposed as methods of the Msvm_VirtualSystemManagementService class.

Creating snapshots of virtual systems

A snapshot is a point-in-time image of a virtual system. It can be seen as a quick way to backup a virtual machine. You can take a snapshot at any time with any guest operating system and can restore a virtual a machine at any stage.

Let see some examples of WMI class to create and apply snapshots.

First you connect to the virtualization service.

PS C:\> $VSService = get-wmiobject –namespace root\virtualization –class Msvm_VirtualSystemManagementService

Use get-member to discover all the methods exposed by this object

PS C:\> $VSService | get-member | where {$_.Membertype -match 'Method'}

Name                            MemberType   Definition
----                            ----------   ----------
AddKvpItems                     Method       System.Management.ManagementBas...
AddVirtualSystemResources       Method       System.Management.ManagementBas...
ApplyVirtualSystemSnapshot      Method       System.Management.ManagementBas...
CloneVirtualSystem              Method       System.Management.ManagementBas...
CreateVirtualSystemSnapshot     Method       System.Management.ManagementBas...
DefineVirtualSystem             Method       System.Management.ManagementBas...
DestroyVirtualSystem            Method       System.Management.ManagementBas...
ExportVirtualSystem             Method       System.Management.ManagementBas...
GetSummaryInformation           Method       System.Management.ManagementBas...
GetVirtualSystemThumbnailImage  Method       System.Management.ManagementBas...
ImportVirtualSystem             Method       System.Management.ManagementBas...
InstantiateVirtualSystem        Method       System.Management.ManagementBas...
ModifyKvpItems                  Method       System.Management.ManagementBas...
ModifyServiceSettings           Method       System.Management.ManagementBas...
ModifyVirtualSystem             Method       System.Management.ManagementBas...
ModifyVirtualSystemResources    Method       System.Management.ManagementBas...
PlanVirtualSystem               Method       System.Management.ManagementBas...
RemoveKvpItems                  Method       System.Management.ManagementBas...
RemoveVirtualSystemResources    Method       System.Management.ManagementBas...
RemoveVirtualSystemSnapshot     Method       System.Management.ManagementBas...
RemoveVirtualSystemSnapshotTree Method       System.Management.ManagementBas...
RequestStateChange              Method       System.Management.ManagementBas...

So you can see that it has some interesting methods!
To create a snapshot, you first identify the virtual system, get its absolute path and use it as a parameter to call CreateVirtualSystemSanpshot.

Using the lab environment I describe here, let consider the IIS-Core virtual system.

PS C:\> $Core = get-wmiobject -namespace root\virtualization -class Msvm_ComputerSystem -filter " ElementName = 'IIS-CORE' "

PS C:\> $VSService.CreateVirtualSystemSnapShot($Core.__PATH)

The call should return 0 or 4096. If not, it means that there is an error in the call.

Finding snapshots of virtual systems

Once a snapshot is taken, its configuration is stored as an instance of the Msvm_VirtualSystemSettingData object. The Msvm_VirtualSystemSetting class is used to represent all virtualization-specific settings for a virtual system which can be either a virtual machine or a snapshot.  A WMI query on this class will return settings of virtual machines and snapshots that currently exist on the host system. To distinguish snapshot from virtual machine, you should filter the query on the property called SettingType. This property can have one of the two values:

    • SettingType = 3. The instance contains settings of a virtual machine
    • SettingType = 5.. The instance contains settings of a snapshot

PS C:\> $VSService = get-wmiobject –namespace root\virtualization –class Msvm_VirtualSystemSettingData -filter "SettingType = 5"

Now that you get a list of snapshots with their settings, how can you find the linkage between snapshots and virtual machine? As you know, a virtual machine can have zero snapshot or several snapshots taken at different points in time. A query to Msvm_VirtualSystemSettingData with a filter on SettingType returns a list of snapshots in the order they are created and they are not sorted per virtual machine!
Fortunately, you can use the Property called SystemName of the Msvm_VirtualSystemSettingData class to identify the associated virtual system. This property contains the object GUID of a virtual machine. This is the same GUID that you find on the Name property of the Msvm_ComputerSystem class. You make a WMI query on the Msvm_ComputerSystem class to get a list of virtual systems that exist on a host. See the discussion of this class here.

With this information, you can now find all snapshots that are associated to a virtual machine.

PS C:\> get-wmiobject -namespace root\virtualization -class Msvm_VirtualSystemData -filter "SystemName=`'$($Core.Name)`' and SettingType = 5”

Applying snapshots to a virtual system

You can apply a snapshot to a virtual machine to restore the system to a state at the time the snapshot was taken. You don't need to apply snapshots in a particular order but can take any snapshot associated to this machine and restore it.
You use the method called ApplyVirtualSystemSnapshot  of the Msvm_VirtualSystemManagementService class to perform the restore operation form a command line. Here is the code:

PS C:\> # Let's assume that you have identified a particular snapshot using the example above and store the object in a variable
PS C:\> # called $ASnapShot

PS C:\> # First you need to sop the virtual machine.
PS C:\> $Core.RequestStateChange(3)

PS C:\> # Then apply a snapshot
PS C:\> $VSService.ApplyVirtualSystemSnapShot($Core.__PATH, $ASnapShot.__PATH)
 

From the Hyper-V Manager console, you will notice that the "restored" virtual system will be put in 'Saved' state mode. Starting it will restore the machine to its state before the snapshot was taken. 

Summary

This entry provides examples of creating, finding and applying a snapshot on a virtual machine using the Hyper-V WMI classes.

Until the next time....
Hope you enjoy it!

/Dung

 

 

1月27日

Hyper-V WMI Examples - Part I

 

Microsoft announced last week the Hyper-V WMI provider and published its documentation here. I find it very interesting for IT Pros like us to build scripts to manage and provision virtual machines through WMI. When combining PowerShell with WMI, you really have powerful tools in your hands for managing virtual environments.

Let's take a look at the Hyper-V WMI provider through some examples.

First you need a minimal environment to work with :=).

  1. You must have at least an x64 box that supports Hardware Assisted Virtualisation (HAV), meaning that the CPU must have Intel-VT or AMD-V enabled for Hyper-V.
  2. You install Windows Server 2008 RC1 with Hyper-V Beta OS on this box
  3. You install the Hyper-V Server Role and Windows PowerShell feature using Server Manager
  4. You use the Hyper-V Manager console to create some virtual machines.

Note: You don't need to install any OS for guest systems, the examples below require some guests running ( even with no OS) to play with WMI.

Here is a screenshot of my lab environment

ScreenShot002

 

Exploring the namespace

All the examples below use Windows PowerShell as scripting language. PowerShell is the next generation of interactive shell from Microsoft. It's very powerful as it is an object-based shell, meaning that all input/output from PowerShell are objects and not text. IT administrators can leverage all objects model (WMI-COM-.NET) exposed by the OS and use them with PowerShell. Today, Windows PowerShell is shipped with Windows Server 2008 and there is a release of PowerShell on the Microsoft web site. Go and take a look at it here: www.microsoft.com/PowerShell 

Enough marketing for PowerShell =) Let's do some work now!

First, open a Windows PowerShell window.
You then need to find the namespace for the Hyper-V WMI provider. For that, use this command:

PS C:\> get-wmiobject -namespace root -class __NAMESPACE | select Name      
Name
-------
subscription
DEFAULT
CIM V2
.......
Virtualization
-----

Note: There are two(2) underscore (_) characters before NAMESPACE

So the namespace for the Hyper-V WMI provider is root\virtualization. So far so good! Let's find all the classes exposed through this WMI provider

PS C:\> get-wmiobject -namespace root\virtualization -list

This command returns all classes that exist under this namespace and you will notice that there are hundreds of them! Their names start with CIM_ or Msvm_. CIM classes provide information about system in general (based on DMTF standard) and Msvm classes are more specific to Windows Virtualization environment.
Let's take a look at some of them. As a matter of fact, you can get detailed documentation of Msvm classes here.

 

The Msvm_ComputerSystem Class

As its name implies, the Msvm_ComputerSystem class contains information about a system which is either a host system or a virtual system (or virtual machine -VM). Use this class as follow:

PS C:\> get-wmiobject -namespace root\virtualization -class Msvm_ComputerSystem

This command returns all instances of Msvm_ComputerSystem, each object represents a virtual system or a host system. The output produces a lot of information as the class has several properties. By the way if you want to find out all properties of the class, simply pipe the previous command to get-member.  Find properties that are of your interest  and filter the output of the previous command to find useful information. In the following example, I will focus on those properties:  ElementName , Name and Caption or Description.

The ElementName attribute is set to the display name of a virtual machine or the NETBIOS name of the host system. The Name attribute contains a GUID of the computer object if the computer is a virtual machine. When the Name contains a “real” name, the corresponding object describes a host system. The Description or Caption attribute can also give some hint about the type of the computer.

In my environment, the output of this command shows that the host system is named VIRIDIAN and is hosting 4 virtual systems

ScreenShot001

To find out all virtual systems on a given host, you can filter the output of the previous command as follow:

PS C:\> get-wmiobject -namespace root\virtualization -class Msvm_ComputerSystem -filter " ElementName <> Name"

Another interesting property is the EnabledState property. According to the documentation here, it indicates the current state of a system. It is always set to 2 ( Enabled) for a host system but for virtual systems, it can take one of the following values:

2 - Enabled ; 3- Disabled; Paused - 32768 ; Suspended - 32769

Values in the range [32770-32775] indicate transitional states of a system: Starting, Suspending, Saving....

Now that you discover, how can you change the state of a given machine? Well, the Msvm_ComputerSystem class has a method called RequestStateChange that you can use to perform actions such as, turn off, pause or save state of a virtual system. Its first parameter is of type Integer and can take on of the values described above. Here is an example:

First find a virtual machine to work with
PS C:\> $Core = get-wmiobject -namespace root\virtualization -class Msvm_ComputerSystem -filter " ElementName = 'IIS-CORE' "

Then check is current state
PS C:\> $Core.EnabledState

Put this machine in saved state
PS C:\> $Core.RequestStateChange(32769)

Start this machine
PS C:\> $Core.RequestStateChange(2)

Isn't it easy?

Summary

In this blog entry, we discover the namespace of the Hyper-V WMI provider and use get-wmiobject to find all the classes exposed through this provider.
We then use the Msvm_ComputerSystem class to find all virtual machines as well as some interesting properties such as ElementName and EnabledState. Finally we call the RequestStateChange method of this class to power-on a VM and save its state.

Hope you enjoy it!

Until the next time....

/Dung