Profiel van Dung K HoangDung's spaceWeblogNetwerk Extra Help

Weblog


    24 april

    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

    21 april

    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

     
    *