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

日志


6月10日

Hyper-V WMI Explained - Part II

 

Management Services

In Hyper-V there are 3 services that govern all management activities of the virtual environment:

  • Hyper-V Virtual Machine Management Service (vmms) - This service is used to control creation, deletion and  modification of virtual machines. It also provides mechanisms to perform operations on virtual machines such as taking snapshots, importing and exporting virtual machines. in Hyper-V WMI, the service is represented by the class Msvm_VirtualSystemManagementService. If you want to take actions on virtual machines, you must first obtain an instance of this class by querying WMI and use one of its public methods.
    Example : $VM_Service = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService

 

  • Hyper-V Networking Management Service (nvspwmi) - This service is used to control creation, deletion of networking resources such as virtual switches, switch ports and internal Ethernet ports.  in Hyper-V WMI, the service is represented by the class Msvm_VirtualSwitchManagementService.
    Note:  the service does not manage network adapters (NICs) of virtual machines. NICs are resources of virtual machines so you need to use the Virtual Management Service.

 

  • Hyper-V Image Management Service (virtsvcs) - This service manages virtual media (.vhd, .vfd) for virtual machines..  in Hyper-V WMI, the service is represented by the class Msvm_ImageManagementService.

The figure below maps various action items shown in the Hyper-V Manager console to the three services described above

Hyper-V-Services

Until the next time!

Enjoy,

/Dung

HyperV WMI PowerShell

Hyper-V WMI Explained - Part I

 

Introduction

I received many requests to explain some PowerShell examples on Hyper-V WMI so now it's great time to start a new series to dive in more detailed explanation about Hyper-V WMI.

First let me say that your support through e-mail in the last few months are exceptional and I'd like to thank all the folks who send comments/suggestions to enhance the examples ( except for some scams in the blog!). Second let me write down a short disclaimer before going into technical details.

 

Disclaimer

All the information provided here are based on my own understanding of Hyper-V WMI during many hours of trials and tests. I use the two documents to learn about Hyper-V WMI:

  1. Hyper-V WMI documentation. The MSDN library contains Beta2 documentation of WMI.  Even though some classes/methods/properties are changed with the current release (Hyper-V RC1), most of them are still valid.
    Note:  I hope that MS will update the library ASAP when Hyper-V hits RTM
  2. DMTF CIM System Virtualization model: This is THE doc that you need to read/consult frequently if you are serious about using WMI and Hyper-V to build management tools. I know that MS is defining/pushing/using standards in the management space, so no surprise that they are using the virtualization model defined by the DMTF task force.

In addition, I extensively use PowerShell and especially the get-member cmdlet to discover methods and properties of WMI object classes. This is a must if you want to write scripts or code against Hyper-V WMI. There certainly are other tools to browse WMI objects and I find Powershell quite handy for me.

Finally, explanations provided are my interpretation of the documentation and based on my own testing. As such all the errors are also mine too!

Now let's start then!

/Dung

HyperV WMI PowerShell

6月6日

Hyper-V WMI Examples - Part XVII

 

Removing virtual machines from Hyper-V

The following script is used to remove virtual machines from the Hyper-V console.

##    Connect to the Virtual Management Service
##
$Server = 'localhost'
$VM_Service = get-wmiobject -computername $server -namespace root\virtualization Msvm_VirtualSystemManagementService
##
## Remove "01_xxxx"Vms from the console
##
$ListofVMs = get-wmiobject -computername $server -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like '*01*'}
foreach ($VM in $ListofVMs)
{
    if ($VM -ne $Null)
    {
    $VM_Service.DestroyVirtualSystem($VM.__PATH)
    }
}

 

Enjoy!

/Dung

HyperV WMI PowerShell

6月3日

Hyper-V WMI Examples - Part XVI

 

Changing the Boot order of a VM

Sometimes you may want to change the Boot order of a VM, for instance, to PXE boot a VM, to boot from a CD/DVD, or to simply fix the order to always start booting from the disk.

You use the Msvm_VirtualSystemSettingData class to change the boot order setting f a VM. Objects of this class represents virtual "motherboard"" of a virtual machine and store virtualization-specific settings of a VM.

 

Script

$VMName = "My Virtual Machine"

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

# Step 1

$VM = get-wmiobject –namespace \root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like $VMName )

# Step 2 - Get its "motherboard"

$MB = get-wmiobject –namespace \root\virtualization Msvm_VirtualSystemSettingData | where {$_.ElementName -like $VMName )

# Step 3 - Change the Boot Order

# Values are 0: Boot from floppy – 1: Boot from CD – 2: Boot from disk – 3:PXE Boot

$MB.BootOrder = 3,1,2,0

# Step 4

$VM_Service.ModifyVirtualSystem($VM.__PATH, $MB.psbase.GetText(1))

 

Et Voilà!

Enjoy!

/Dung

HyperV WMI PowerShell

5月27日

Hyper-V WMI Examples - Part XV

 

Creating a new virtual machine from an existing virtual hard disk

Due to numerous requests, I dedicate this entry to talk about creating a virtual machine from an existing virtual hard disk. It seems that some of you were not able to get it working using the example of adding a DVD as resource to an existing VM. I must admit that it's not intuitive and I still have to do it several times to make it right.
Note:  The script is tested against Hyper-V RC1.

 

Goal

Create a new virtual machine based on an existing virtual hard disk. The VHD file is called C:\W2K3.VHD and the disk will be created on IDE Controller 0 at location 0.

High level steps
  1. Create a new virtual machine
  2. Locate the IDE Controller 0
  3. Get the default Disk Drive instance. Create a new instance from the default one. Attach it to the IDE Controller 0 at location 0. Add the disk drive as new resource to the VM
  4. Get the default virtual hard disk instance. Create a new instance from the default one. Attach it to the disk drive. Connect it to the VHD file. Add the disk drive as new resource to the VM
Script

$VHDFile = "C:\W2K3.vhd"

# Step 1

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

if ($status.ReturnValue -eq 0)
{
    $NewVM_PATH = $status.DefinedSystem
}

# Step 2

$ListOfControllers = get-wmiobject -namespace root\virtualization Msvm_ResourceAllocationSettingData `
                                    | where {$_.ResourceSubType -like "*Emulated*IDE*"}
foreach ($Controller in $ListOfControllers)
{
            if ($Controller.Address -eq 0)
            {
            # It must return exactly one controller. Let's assume that is the case
            $IDEController0 = $Controller
            }
}

# Step 3

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

$DiskDrive = $DiskDefault.psbase.Clone()
$DiskDrive.Parent = $IDEController0.__PATH          # Attach to IDE Controller 0
$DiskDrive.Address = 0                                                 # at Location 0
$Status = $VM_Service.AddVirtualSystemResources($NewVM_PATH, $DiskDrive.psbase.GetText(1))
if ($Status.ReturnValue –eq 0)
{
             $NewDiskDrive_PATH = $Status.NewResources
}

# Step 4

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

$NewDiskDrive = [WMI]"$NewDiskDrive_PATH"
$VHDisk = $VHDDefault.psbase.Clone()
$VHDisk.Parent = $NewDiskDrive.__PATH            # Attach to the disk drive
$VHDisk.Connection = $VHDFile
$VM_Service.AddVirtualSystemResources($NewVM_PATH, $VHDisk.psbase.GetText(1))

 

Enjoy!

/Dung

HyperV WMI PowerShell

5月17日

Hyper-V WMI Examples - Part XIV

 

Hyper-V Virtual Networks - Connecting virtual machines to a virtual network

Now that you know how to create virtual networks, let me show how to connect a NIC of a given virtual machine to a network

The script below is extracted from a discussion in the Virtualization Technet Forum. All credits go to AggieMatt!

## Assumes that  you already identify a virtual switch and store it in a variable called $Switch

## Create a new SwitchPort
$VSwitch_Mgmt = gwmi -namespace root/virtualization Msvm_VirtualSwitchManagementService
$VSwitch = gwmi -namespace root/virtualization Msvm_VirtualSwitch
$PortName = "MyPortName"
$Scope = ""
$Status = $VSwitch_Mgmt.CreateSwitchPort($VSwitch, $PortName, $PortName, $Scope)
$NewPortPath = $Status.CreatedSwitchPort
## Add a new SyntheticEthernetPort
$DefaultNIC = gwmi -namespace root/virtualization Msvm_SyntheticEthernetPortSettingData | where {$_.InstanceID -like "*Default*"}
$NewSyntheticNIC = $DefaultNIC.psbase.Clone()
$NewSyntheticNIC.Connection = $NewPortPath
$NewSyntheticNIC.ElementName = "Network Adapter"
$SyntheticNICGUID = [guid]::NewGuid().ToString()
$NewSyntheticNIC.VirtualSystemIdentifiers = "{" + $SyntheticNICGUID + "}"
## Apply the settings to the selected computer
$VM_Mgmt = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemManagementService
$VMName = "MyVMName"
$VM = get-wmiobject -namespace root\virtualization Msvm_ComputerSystem | where {$_.ElementName -like $VMName}
$VM_Mgmt.AddVirtualSystemResources($VM.__PATH, $NewSyntheticNIC.psbase.gettext(1))

Enjoy!

/Dung

HyperV WMI PowerShell

Hyper-V WMI Examples - Part XII

 

Hyper-V Virtual Networks - Creating External Virtual Networks

Finally let's see how you can create an External virtual network. Here is an overview of high level steps:

External Virtual Network
  1. Find the Msvm_ExternalEthernetPort instance associated to a physical network adapter
  2. Call CreateSwitch to create a virtual network.
  3. Call CreateSwitchPort  to create at least 2 ports on the switch
  4. Call SetupSwitch  to create an external virtual network
Script

# Step 0: Connect to the Virtual Network Management Service
$SW_Service = get-wmiobject –namespace root\virtualization Msvm_VirtualSwitchManagementService

# Step 1
$ThisPhysicalAdapter = get-wmiobject -namespace root\virtualization msvm_ExternalEthernetPort -filter "Name = 'Broadcom BCM5708C NetXtreme II GigE (NDIS VBD Client) #2' "

## Change the name used above to the name of your network adapter.

# Step 2
$Status = $SW_Service.CreateSwitch("External_Network", "External Virtual Network", 1024, "")

# Store the path for later use
$External_SwitchPATH = $Status.CreatedSwitchService

# Step 3: Create two ports on the switch
# Port for Internal
$Status = $SW_Service.CreateSwitchPort($External_SwitchPATH, "Internal_Port" , "Internal Port for Host")

# Store the path for later use
$InternalSwitchPortPATH = $Status. CreatedSwitchPort

# Port for External
$Status = $SW_Service.CreateSwitchPort($External_SwitchPATH, "External_Port" , "External Port")

# Store the path for later use
$ExternalSwitchPortPATH = $Status. CreatedSwitchPort

# Step 4
$Status = $SW_Service.SetupSwitch($ExternalSwitchPortPATH, $InternalSwitchPortPATH, $ThisPhysicalAdapter, "Internal Network Adapter", "Internal NIC to External Virtual Network")

Enjoy!

/Dung

HyperV WMI PowerShell

5月15日

Hyper-V WMI Examples - Part XI

 

Hyper-V Virtual Networks - Creating Internal Virtual Networks

Let's talk about how to create Internal Virtual Networks. In my previous post, I described the concept and high level steps to create internal virtual network.

Steps to create a Internal Virtual Network
  1. Call CreateInternalEthernetPort to create a virtual NIC on the Hyper-V host system.
  2. Find the LAN Endpoint  associated to this virtual NIC by querying Msvm_LANEndPoint
  3. Call CreateSwitch to create a virtual network.
  4. Call CreateSwitchPort  to create at least one port on the switch
  5. Call ConnectSwitchPort to connect the port with the LAN Endpoint
Script

$SW_Service = get-wmiobject –namespace root\virtualization Msvm_VirtualSwitchManagementService

## Step 1

$Status = $Sw_Service.CreateInternalEthernetPort("Internal Network Adapter", "Internal NIC", "020304050607" )

if ($Status.ReturnValue -eq 0)

{
write-host "Internal Ethernet Port successfully created"
$InternalEtherPortPATH = $Status.CreatedInternalEthernetPort
}

## Step 2

$NIC_Port = [WMI]$InternalEtherPortPATH
# Get the name of this NIC
$NIC_Name = $NIC_Port.Name

# Find the LANEndPoint associated to this NIC
$LANEndPoint = get-wmiobject -namespace root\virtualization Msvm_LanEndPoint -filter "Name = `'$($NIC_Name)`'"

## Step 3

$Status = $SW_Service.CreateSwitch(“Internal_Network”, “Host and Guests Virtual Network”, 1024, “”)

if ($Status.ReturnValue -eq 0)

{
write-host "Switch successfully created"
$SwitchPATH = $Status.CreatedSwitchService
}

## Step 4

$Status = $SW_Service.CreateSwitchPort($SwitchPATH, "Internal_Port" , "Internal Port for Host")

if ($Status.ReturnValue -eq 0)

{
write-host "SwitchPort successfully created"
$PortPATH = $Status.CreatedSwitchPort
}

## Step 5

$Status = $SW_Service.ConnectSwitchPort($PortPATH , $LANEndPoint)

## Additional Step - Create a port to connect VM

$Status = $SW_Service.CreateSwitchPort($SwitchPATH, "One_Port" , "A Switch Port to connect VM")

if ($Status.ReturnValue -eq 0)

{
write-host "SwitchPort successfully created"
$PortPATH = $Status.CreatedSwitchPort
}

 

Enjoy!

/Dung

 HyperV WMI PowerShell

5月13日

Hyper-V WMI Examples - Part X

Hyper-V Virtual Networks - Creating Private Virtual Networks

In a previous post, I give you an overview of virtual networks and high-level steps to create virtual networks. Let's put it in practice today and show how to create a private virtual network.

Steps to create a Private virtual network
  1. Call CreateSwitch to create a virtual network. By default, this method creates a private virtual network
  2. Call CreateSwitchPort  to create ports on the switch
Script

$SW_Service = get-wmiobject –namespace root\virtualization Msvm_VirtualSwitchManagementService

# Call CreateSwitch
# 1024 represents the max number of MAC addresses learnable by the switch
# The 4th parameter represents the scope of residence and is not currently defined and used

$Status = $SW_Service.CreateSwitch(“Private_Network”, “Guest only Virtual Network”, 1024, “”)

if ($Status.ReturnValue -eq 0)

{
write-host "Switch successfully created"
$SwitchPATH = $Status.CreatedSwitchService
}

## Create a SwitchPort

$Status = $SW_Service.CreateSwitchPort($SwitchPATH, "One_Port" , "A Switch Port to connect VM")

if ($Status.ReturnValue -eq 0)

{
write-host "SwitchPort successfully created"
$PortPATH = $Status.CreatedSwitchPort
}

 

Enjoy!

/Dung

 HyperV WMI PowerShell

5月12日

Hyper-V WMI Examples - Part IX

 

Hyper-V Virtual Networks

Up to now, we've spent a significant amount of time and blog entries to talk about virtual machines. Let's switch gear and discuss about virtual networks.

Networking Concepts

In Hyper-V, you create virtual networks and connect virtual network cards (NICs) of virtual machines to allow communications between the machines themselves, the host system and eventually the physical network.

A virtual network, also called Virtual Switch can be one of the three following types:

· Private: Virtual machines connected to this network can communicate between them. The host system has no connectivity with virtual machines

· Internal: Virtual machines connected to this network can communicate between themselves and the host system. There is no connectivity with the physical network.

· External: An external virtual network binds to the physical network adapter so that virtual machines as well as the host system can access the physical network.

Virtual networks and connections of virtual machines to virtual networks are managed by a Hyper-V service called Virtual Switch Management Service. There is a WMI class associated to this service called Msvm_VirtualSwitchManagementService.

 
Private Virtual Network

When you create a private virtual network, the Virtual Network Manager Service running on the host system will create a Virtual Switch and allows you to connect virtual machines to this switch. The host system does not participate in this private network, as such, cannot communicate with virtual machines connected to it. This type of network is also known as "Guest-Only Network" or "Private Virtual Machine Network". The figure below shows a visual representation of a private virtual network.

 image

 

 

 

 

 

 

 

 

 

 

Internal Virtual Network

When you create an Internal virtual network, the Virtual Network Manager Service running on the host system will create:

· A virtual network

· A virtual NIC on the host system that will be connected to the virtual network.

As such, all virtual machines connected to the Internal virtual network can communicate with the host system and vice-versa. It is important to note that existing physical network adapters are left untouched. The figure below shows a visual representation of an internal virtual network.

 image

 

 

External Virtual Network

When you create an External virtual network, you specify a physical network adapter for the virtual network to bind to. As a consequence, the Virtual Network Manager Service running on the host system will create:

· A virtual network

· A virtual NIC on the host system that will be connected to the virtual network

The physical network adapter will then be connected to the virtual network. The latter will be acting as a router and allow both virtual machines and host system to connect to the physical network. Figure 3 illustrates the concept of an external virtual network.

It's interesting to note that:

  • all the existing network connections to the host system will be lost as soon as you create an external virtual network that binds to a unique physical NIC of the host system. The host is now “connected” to the physical network through the virtual NIC and the virtual “switch”
  • You cannot create an external virtual networks that is bound to a wireless adapter.

The figure below illustrates the concept of an external virtual network.

image

 

 

How to connect a virtual machine to a virtual network?

Now that you understand the concept of virtual network, your next question would be to connect a virtual machine to a virtual network.

Assume that your virtual machine already has a NIC and that you have created a virtual network, you will need to create a port on the virtual network, or to be exact, create a SwitchPort, and then associate this SwtichPort to a NIC by setting  the Connection property of the NIC to the WMI Path of the SwitchPort.

If your virtual machine does not have a NIC, you need to create one by duplicating the default instance of Msvm_SyntheticEthernetPortSettingData and perform the same operations as above.

Overview of Msvm_VirtualSwitchManagementService

The Msvm_VirtualSwitchManagementService class is used to control the creation and configuration of virtual networks. As you can see from the explanations above, there are two distinct tasks in virtual networks management. First you create a virtual network and define its type – private, internal, external. Once the virtual network created, you then create ports on the switch for network connections. Second you connect virtual NICs (either from virtual machines or the host system) to a virtual network. The Msvm_VirtualSwitchManagementService class provides several methods to create virtual networks and configure its type. Creating a virtual network is very easy and consists of a single-step operation. To configure the type, you may need additional steps.

Here is a high-level overview of steps to create and configure virtual networks. All the methods listed below come from the Msvm_VirtualSwitchManagementService class.

Private Virtual Network
  1. Call CreateSwitch to create a virtual network. By default, this method creates a private virtual network
  2. Call CreateSwitchPort  to create ports on the switch
Internal Virtual Network
  1. Call CreateInternalEthernetPort to create a virtual NIC on the Hyper-V host system.
  2. Find the LAN Endpoint  associated to this virtual NIC by querying Msvm_LANEndPoint
  3. Call CreateSwitch to create a virtual network.
  4. Call CreateSwitchPort  to create at least one port on the switch
  5. Call ConnectSwitchPort to connect the port with the LAN Endpoint

 

External Virtual Network
  1. Find the Msvm_ExternalEthernetPort instance associated to a physical network adapter
  2. Call CreateSwitch to create a virtual network.
  3. Call CreateSwitchPort  to create at least 2 ports on the switch
  4. Call SetupSwitch  to create an external virtual network

That's it!

Until next time...

/Dung

 HyperV WMI PowerShell

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