August, 2009

  • TONYSO

    Hyper-V How To: Detect if you are inside a VM

    • 1 Comments

    Sometimes, when troubleshooting or for forensic reasons, you may have to determine if an application is running inside a virtual machine. John Kelbley, co-author of Windows Server 2008 Hyper-V : Insiders Guide to Microsoft's Hypervisor, shares how.

    One (relatively) simple way to detect key virtualization information is via WMI / WBEM.  You can use the root\CIM2 namespace and access  the Baseboard class (full of interesting BIOS information) to get a description of the "physical" system.  This class often includes information about the motherboard and chassis  - manufacture, model, serial number, other.   You can run the following VBS to get this info.

    On Error Resume Next

    Const wbemFlagReturnImmediately = &h10
    Const wbemFlagForwardOnly = &h20

    arrComputers = Array(".")
    For Each strComputer In arrComputers
       WScript.Echo
       WScript.Echo "=========================================="
       WScript.Echo "Computer: " & strComputer
       WScript.Echo "=========================================="

       Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
       Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", _
                                              wbemFlagReturnImmediately + wbemFlagForwardOnly)

       For Each objItem In colItems
          WScript.Echo "Caption: " & objItem.Caption
          strConfigOptions = Join(objItem.ConfigOptions, ",")
             WScript.Echo "ConfigOptions: " & strConfigOptions
          WScript.Echo "   CreationClassName: " & objItem.CreationClassName
          WScript.Echo "         Description: " & objItem.Description
          WScript.Echo "        HostingBoard: " & objItem.HostingBoard
          WScript.Echo "         InstallDate: " & WMIDateStringToDate(objItem.InstallDate)
          WScript.Echo "        Manufacturer: " & objItem.Manufacturer
          WScript.Echo "               Model: " & objItem.Model
          WScript.Echo "                Name: " & objItem.Name
          WScript.Echo "OtherIdentifyingInfo: " & objItem.OtherIdentifyingInfo
          WScript.Echo "          PartNumber: " & objItem.PartNumber
          WScript.Echo "             Product: " & objItem.Product
          WScript.Echo "        SerialNumber: " & objItem.SerialNumber
          WScript.Echo "                 SKU: " & objItem.SKU
          WScript.Echo "              Status: " & objItem.Status
          WScript.Echo "                 Tag: " & objItem.Tag
          WScript.Echo "             Version: " & objItem.Version
          WScript.Echo
       Next
    Next

    Function WMIDateStringToDate(dtmDate)
    WScript.Echo dtm:
        WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _
        Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
        & " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
    End Function

    Here is a screen capture of the script results for a physical system running Windows Server 2008. 

    image

    NOTE the motherboard was manufactured by Intel  (model DG45ID).

    Running the same script in a virtual machine returns similar information:

    image

    NOTE On the virtual machine, the "motherboard" appears to be made by Microsoft (we don't make motherboards!) and is of a virtual type.

    The version number shown reflects the version of Hyper-V (Server 2008 RTM), and the Serial Number matches that found in the VM configuration file (XML file on the physical host).

    The Perl script version for this is:

    use strict;
    use Win32::OLE('in');

    use constant wbemFlagReturnImmediately => 0x10;
    use constant wbemFlagForwardOnly => 0x20;

    my @computers = (".");
    foreach my $computer (@computers) {
       print "\n";
       print "==========================================\n";
       print "Computer: $computer\n";
       print "==========================================\n";

       my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n";
       my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL",
                      wbemFlagReturnImmediately | wbemFlagForwardOnly);

       foreach my $objItem (in $colItems) {
          print "          Caption: $objItem->{Caption}\n";
          print "       ConfigOptions: " . join(",", (in $objItem->{ConfigOptions})) . "\n";
          print "   CreationClassName: $objItem->{CreationClassName}\n";
          print "         Description: $objItem->{Description}\n";
          print "        HostingBoard: $objItem->{HostingBoard}\n";
          print "         InstallDate: $objItem->{InstallDate}\n";
          print "        Manufacturer: $objItem->{Manufacturer}\n";
          print "               Model: $objItem->{Model}\n";
          print "                Name: $objItem->{Name}\n";
          print "OtherIdentifyingInfo: $objItem->{OtherIdentifyingInfo}\n";
          print "             Product: $objItem->{Product}\n";
          print "        SerialNumber: $objItem->{SerialNumber}\n";
          print "                 SKU: $objItem->{SKU}\n";
          print "              Status: $objItem->{Status}\n";
          print "                 Tag: $objItem->{Tag}\n";
          print "             Version: $objItem->{Version}\n";
          print "\n";
       }
    }sub WMIDateStringToDate(strDate)
    {
       return "blah";
    }

    For additional reference, within Windows I could also access  the same information in a single command line (in Windows XP or newer) by typing  the following:

         wmic baseboard get manufacturer, product, Serialnumber, version

    image

    For info on how to use Hper-V PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

    And buy John(et al)’s book!

    image

    Update: John's blogging now and has an updated method to detect the hypervisor: http://blogs.technet.com/enterprise_admin/archive/2009/10/20/detecting-the-virtualization-layer-from-within-a-guest-child-instance.aspx

  • TONYSO

    Hyper-V R2 How To: Move a VM + storage + snapshots

    • 0 Comments

    Want to move a VM from server A to server B along with its associated storage and snapshots in R2? Snapshots are associated with the VMs and not the VHD files. You should explore import/export. Soumya’s written a series of blogposts to get you started:

    http://blogs.technet.com/virtualization/archive/2009/05/20/hyper-v-r2-import-export-part-1-the-case-for-new-import-export-functionality.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/21/hyper-v-r2-import-export-part-2-the-new-import-export-apis.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/22/hyper-v-r2-import-export-part-3-the-ui.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/27/hyper-v-r2-import-export-part-4-export-code-sample.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/28/hyper-v-r2-import-export-part-5-import-code-sample.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/29/hyper-v-r2-import-export-part-6-so-what-happened-to-configuration-only-export.aspx

    Ben blogged about V1 (also called R1 now by some folks…) import/export: 
    http://blogs.msdn.com/virtual_pc_guy/archive/2008/08/26/hyper-v-export-import-part-1.aspx
    http://blogs.msdn.com/virtual_pc_guy/archive/2008/08/27/hyper-v-export-import-part-2.aspx

  • TONYSO

    Hyper-V How To: Modify VM VLAN IDs for Server Core using Script

    • 0 Comments

    Need to remotely set the VLAN IDs on your server core installation? Some friends on the Hyper-V team put together a powershell 2.0 script for setting vlan id which you could run on the server core directly (rename the extension of the script to .ps1). The script accepts a vm name, and vlan id, finds the first connected network adapter of that vm and sets it to that vlan id.

    ################################################################################
    #
    #   Copyright ©2009 Microsoft Corporation.  All rights reserved.
    #
    #   File: modify-vlan.ps1
    #
    #   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    #   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    #   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    #   PARTICULAR PURPOSE.
    #
    #   Copyright ©2009 Microsoft Corporation.  All rights reserved.
    #
    ################################################################################

    param(
        $vmName = $(throw "Must supply a virtual machine name"),
        $vlanId = $(throw "Must supply  vlan id"),
        $computer = "."
    )

    $ns = "root\virtualization"

    # get the computer system
    $vm = gwmi -namespace $ns -computerName $computer Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    if ($vm -eq $null)
    {
       "No virtual machine with name '$vmName'"
       return
    }

    # get its related vssd
    $vssd = gwmi -namespace $ns -computerName $computer -query "associators of {$vm} where AssocClass=Msvm_SettingsDefineState"

    # get its synthetic and enumlated NICs
    $nics = gwmi -namespace $ns -computerName $computer -query "associators of {$vssd} where AssocClass=Msvm_VirtualSystemSettingDataComponent" |
        where {$_.ResourceType -eq 10 -and ($_.ResourceSubType -eq 'Microsoft Synthetic Ethernet Port' -or
                                            $_.ResourceSubType -eq 'Microsoft Emulated Ethernet Port')}

    if ($nics -eq $null)
    {
       # vm does not have any NICs.
       "Virtual machine '$vmName' does not have any NICs"
       return

    # Find the first nic which has a connection
    $nic = $nics | where {$_.Connection -ne $null} | select-object -first 1

    if ($nic -eq $null)
    {
        "None of the NICs on virtual machine '$vmName' are connected"
        return
    }

    # get the connected switch port.
    $connectedPort = [wmi]$nic.Connection[0]

    # need to set the external trunk list of the external port on this same switch
    # to include this vlan id, else traffic won't get through.

    # first get its switch.
    $switch = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_HostedAccessPoint"

    # enumerate all of its ports. Find the port which is externally connected.
    $ports = gwmi -namespace $ns -computerName $computer -query "associators of {$switch} where ResultClass=Msvm_SwitchPort"
    $externalPort = $null

    foreach ($p in $ports)
    {
       $switchLanEndpoint = gwmi -namespace $ns -computerName $computer -query "associators of {$p} where ResultClass=Msvm_SwitchLanEndpoint"
       if ($switchLanEndpoint -ne $null)
       {
          $externalEthernetPort = gwmi -namespace $ns -computerName $computer -query "associators of {$switchLanEndpoint} where resultclass=Msvm_ExternalEthernetPort"
          if ($externalEthernetPort -ne $null)
          {
             # we got it, we found the switch port connected to the external
             # port, save it and break out of the loop.
             $externalPort = $p
             break
          }
       }
    }

    if ($externalPort -ne $null)
    {
         # get the port's VlanEndpoint
         $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$externalPort} where AssocClass=Msvm_BindsTo"
         # get the vlan's setting object
         $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"

         # get the current trunk list and add the new vlan id into it.
         # one thing additionally we could do here, which the Hyper-V UI does is clean up
         # the old AccessVlan id of the port from the trunk list. But, we can't just remove the
         # old AccessVlan from the trunklist, because another port might be using the same vlan id.
         # We would have to enumerate all of the ports on the switch and build a new trunk list.
         # For the purposes of this script, don't worry about cleaning up old vlan id' from the trunk list.
         $trunkList = $vlanSetting.TrunkedVLANList
         if ($trunkList -notcontains $vlanid)
         {
            $trunkList = $trunkList + $vlanId
            $vlanSetting.TrunkedVLANList = $trunkList
            $result = $vlanSetting.Put()
         }
         # set the vlan mode into trunking mode.
         if ($vlan.DesiredEndpointMode -ne 5)
         {
            $vlan.DesiredEndpointMode = 5
            $result = $vlan.Put()
         }
    }

    # Now that we have finished with the trunklist, set the vlan id of the original connected port.

    $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_BindsTo"
    $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"
    $vlanSetting.AccessVlan = $vlanId
    $result = $vlanSetting.Put()

    ################################################################################
    #
    #   .SYNOPSIS
    #
    #       Sets the vlan id of the first connected NIC on a virtual machine.
    #      
    #
    #   .DESCRIPTION
    #
    #       Finds the first connected NIC of a virtual machine and sets up its VLAN
    #       settings in the same manner as the Hyper-V UI. First it checks to see if
    #       the NIC is connected to an external network, and if so it adds the VLAN id
    #       to the trunking list, and sets the endpoint mode to trunking. This makes sure
    #       that traffic with that VLAN id from the external network goes through the switch.
    #       Next it sets up the Access VLAN of the virtual machine's NIC.
    #
    #   .PARAMETER VmName
    #
    #       The name of the virtual machine to modify. We will modify the first connected
    #       NIC we find on this virtual machine.
    #
    #   .PARAMETER VlanId
    #
    #       The vlan id to set.
    #
    #   .PARAMETER Computer
    #
    #       The host computer where $vmname resides.
    #
    #   .EXAMPLE
    #
    #       C:\PS> mount-vlan.ps1 foo 512
    #
    #
    ################################################################################

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Build a Virtualized Test Infrastructure

    • 0 Comments

    I recently had the opportunity to chat with Rodney Fournier, Senior PFE at Microsoft, about building and running a testing infrastructure with our virtualization and management products, including Hyper-V R2, SCVMM, Operations Manager, Configurations Manager, PowerShell, well…Rod works with the whole stack basically. You kind of have to work with the whole stack to get a good pre-production test, don’t you?

    Click on the image to hear the 10 minute audio podcast.

    NetworkMixThumbnail

    Some useful links if you are in the same situation:

     

  • TONYSO

    Hyper-V How To: Find the right Hyper-V Cmdlet

    • 1 Comments

    Jamesone’s excellent PowerShell Management Library for Hyper-V includes a Hyper-V cmdlet documentation PDF file that helps you  chunk all the things you can do with Hyper-V using PS, for example, the following list of cmdlets parsed by function:

    Admin functions not specific to Hyper-V

    • Test-Admin Tests if the Powershell session is privileged
    • Get-ScriptPath Returns the path to the script
    • Choose-List Allows the user to select a item from a list view
    • Choose-Tree Allows the user to select a item from a tree view
    • Out-Tree Prevents items in a tree view
    • New-zip Creates a new .ZIP archive file
    • Add-ZIPContent Adds files to a .ZIP archive file
    • Copy-ZIPContent Copies files to from .ZIP archive file
    • Get-ZIPContent Gives a lists of items in a ZIP archive file

    Conversion functions

    • Convert-DiskIDtoDrive Converts a drive ID number into it’s associated drive letters
    • Convert-VMState Converts th number for a VM state into the state’s name

    Functions for Hyper-V Servers

    • Get-VMHost Gets a list of Hosts running Hyper-V from Active directory

    Functions for checking WMI jobs created through Hyper-v

    • Test-WMIJob Checks on the state of job – can wait until it completes

    Virtual Machine

    • Choose-VM Allows the user to select VMs from a list
    • Get-VM Retuns WMI objects representing VMs
    • New-VM Creates a new VM
    • Set-VM Sers the properties of an Existing VM
    • Remove-VM Deletes a VM
    • Export-VM Invokes Hyper-Vs export process
    • Import-VM Invokes Hyper-Vs import process
    • Ping-VM Ping FQDNs found via KVP exchange integration component
    • Shutdown-VM Shuts down a VM’s OS cleanly via shutdown integration compoent
    • Start-VM Starts a VM or restarts a saved one
    • Stop-VM Powers down a VM without asking the OS to shutdown first
    • Suspend-VM Puts the VM into a saved state
    • Set-VMState Called by Start, stop and suspend VM set the requested states
    • Get-VmBackupScript Gets a script for backing up one or more VMs
    • Get-VMByMACaddress Discovers a VM from its MAC address
    • Get-VMJPEG Gets a JPEG image of the currect VM screen
    • Test-VMHeartBeat Tests the responses from the heartbeat integration component
    • Get-VMSettingData Returns the Setting data object for the VM
    • New-VMConnectSession Launches a VM connect session to a VM.

    VM Memory

    • Get-VMMemory Returns the amount of memory assigned to a VM
    • Set-VMMemory Sets the amount of memory assigned to a VM

    VM Processors

    • Get-VMCPUCount Gets the number and weighting of Processors assigned to VMs
    • Set-VMCPUCount Sets the number of Virtual Processors assigned to VMs
    • Get-VMProcessor Gets active Virtual Processors and their load data

    VM Disk Controllers

    • Get-VMDiskController Gets an IDE or SCSI controller (IDE controllers can’t be changed)
    • Add-VMSCSIcontroller Adds a synthetic SCSI controller to a VM
    • Remove-VMSCSIcontroller Removes a synthetic SCSI controller from a VM

    Hard disk and DVD drive objects

    • Add-VMDRIVE Connects a Harddisk drive or DVD drive to a controller
    • Remove-VMDRIVE removes a Hard disk drive or DVD drive from a controller
    • Get-VMDriveByController Gets the drives attached to a controller

    Hardisk and DVD disk Image object

    • Add-VMDisk Mounts a DVD or Hard disk image into a Drive
    • Get-VMDisk Gets a list of Virtual disk images in use
    • Set-VMDisk changes the disk image attached to a drive
    • Get-VMDiskByDrive Gets the VM disk image attached to a drive
    • Add-VMNewHardDisk Attaches a new virtual hard disk image to a new drive

    Virtual Hard disk image files

    • Get-VhdDefaultPath Gets the Default path Used by Hyper-v for VHD files
    • Get-VHDInfo Gets information about a VHD, such as its parent, size on disk
    • New-VHD Creates a new VHD file
    • Test-VHD Tests that a VHD can be mounted, and any parent is mountable
    • Compact-VHD Compacts a dynamic VHD file to save space on the host
    • Convert-VHD Changes a VHD from one type to another
    • Expand-VHD Expands the size of a virtual hard disk
    • Merge-VHD Merges the a child VHD with its parent to form a new disk
    • Mount-VHD Makes the VHD file appear as a local disk on the host
    • UnMount-VHD Reverses the mount process so the VHD can be used by a VM

    VM Floppy Disk

    • New-VFD Creates a new floppy disk image file
    • Add-VMFloppyDisk Mounts the Floppy disk in the floppy drive of a VM
    • Get-VMFloppyDisk Returns information about the mounted floppy disk
    • Remove-VMFloppyDisk Ejects any floppy disk from the drive of a VM

    Resource Allocation Settings data objects


    • New-VMRasd Creates objects used by other functions to describe VM components

    Serial Port Objects


    • Get-VMSerialPort Returns information about serial
    • Set-VMSerialPort Maps Serial ports on a VM to Named Pipes

    Ethernet Cards

    • Add-VMNic Adds a Nic to a VM
    • Choose-VMNic Allows the user to select a NIC attached to a virtual machine
    • Get-VMNic Returns information about network cards
    • Remove-VMNic Removes a NIC from a VM
    • Set-VMNICAddress Sets the MAC address for a NIC
    • Set-VMNICSwitch Connects a NIC to a virtual Switch
    • Get-VMNicport Gets the Switch port attached to a NIC
    • Get-VMnicSwitch Returns the Switch a NIC is connected to

    Ethernet Switches

    • Choose-VMExternalEthernet Allows the user to choose a host network card
    • New-VMExternalSwitch Creates a Virtual Switch connect to a host network card
    • New-VMInternalSwitch Creates a Virtual Switch accessible to VMs and the Host
    • New-VMPrivateSwitch Creates a Virtual Switch accessible to VMs
    • Choose-VMSwitch Allows the user to choose a virtual switch
    • Get-VMSwitch Returns information about virtual switches
    • New-VMSwitchPort Defines a new port on a virtual switch

    Key value Pairs

    • Get-VMKVP Gets Key/value pair information sent to the Host by Virtual Machines
    • Add-VMKVP Adds a Key/value pair to the list sent to VMs by the host
    • Remove-VMKVP Removes a Key/value pair from the list sent to VMs by the host

    Snapshots

    • Apply-VMSnapshot Applies a snapshot to a VM
    • Choose-VMSnapshot Allows the user to choose a snapshot
    • Get-VMSnapshot Gets information about snapshots
    • Get-VMSnapshotTree Formats the view of Snapshots as a tree
    • New-VMSnapshot Creates a new snapshot of a VMRemove-VMSnapshot Deletes a snapshot or tree of snapshots
    • Rename-VMSnapshot Renames a snapshot
    • Update-VMSnapshot Deletes a snapshot, and creates a new one with same name

    Did I mention the Management Library is free-as-in-beer?

    Want to know more about James? See http://blogs.technet.com/tonyso/archive/2009/06/24/a-day-in-the-life-of-an-it-pro-evangelist-james-o-neill.aspx

    For more Hyper-V scripts, see the Official Scripting Guys Forum.

  • TONYSO

    Hyper-V How To: Create a VM using Script

    • 2 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for creating a VM:

    # Create a VM

    param(
        [string]$vmName = $(throw "Must supply a virtual machine name")
    )

    # Get a new instance of Msvm_VirtualSystemGlobalSettingData
    $vsgsdClass = [wmiclass]"root\virtualization:Msvm_VirtualSystemGlobalSettingData"
    $vsgsd = $vsgsdClass.CreateInstance()
    $vsgsd.ElementName = $vmName

    # Get the managment service and define the system from the embedded instance
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.DefineVirtualSystem($vsgsd.GetText(1))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Modify VLAN Settings using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for modifying hte VLAN settings on your VMs:

    # Modify VLAN setting for VM

    param(
        $vmName = $(throw "Must supply a virtual machine name"),
        $vlanId = $(throw "Must supply  vlan id"),
        $computer = "."
    )

    $ns = "root\virtualization"

    # get the computer system
    $vm = gwmi -namespace $ns -computerName $computer Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    if ($vm -eq $null)
    {
       "No virtual machine with name '$vmName'"
       return
    }

    # get its related vssd
    $vssd = gwmi -namespace $ns -computerName $computer -query "associators of {$vm} where AssocClass=Msvm_SettingsDefineState"

    # get its synthetic and enumlated NICs
    $nics = gwmi -namespace $ns -computerName $computer -query "associators of {$vssd} where AssocClass=Msvm_VirtualSystemSettingDataComponent" |
        where {$_.ResourceType -eq 10 -and ($_.ResourceSubType -eq 'Microsoft Synthetic Ethernet Port' -or
                                            $_.ResourceSubType -eq 'Microsoft Emulated Ethernet Port')}

    if ($nics -eq $null)
    {
       # vm does not have any NICs.
       "Virtual machine '$vmName' does not have any NICs"
       return

    # Find the first nic which has a connection
    $nic = $nics | where {$_.Connection -ne $null} | select-object -first 1

    if ($nic -eq $null)
    {
        "None of the NICs on virtual machine '$vmName' are connected"
        return
    }

    # get the connected switch port.
    $connectedPort = [wmi]$nic.Connection[0]

    # need to set the external trunk list of the external port on this same switch
    # to include this vlan id, else traffic won't get through.

    # first get its switch.
    $switch = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_HostedAccessPoint"

    # enumerate all of its ports. First the port which is externally connected.
    $ports = gwmi -namespace $ns -computerName $computer -query "associators of {$switch} where ResultClass=Msvm_SwitchPort"
    $externalPort = $null

    foreach ($p in $ports)
    {
       $switchLanEndpoint = gwmi -namespace $ns -computerName $computer -query "associators of {$p} where ResultClass=Msvm_SwitchLanEndpoint"
       if ($switchLanEndpoint -ne $null)
       {
          $externalEthernetPort = gwmi -namespace $ns -computerName $computer -query "associators of {$switchLanEndpoint} where resultclass=Msvm_ExternalEthernetPort"
          if ($externalEthernetPort -ne $null)
          {
             # we got it, we found the switch port connected to the external
             # port, save it and break out of the loop.
             $externalPort = $p
             break
          }
       }
    }

    if ($externalPort -ne $null)
    {
         # get the port's VlanEndpoint
         $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$externalPort} where AssocClass=Msvm_BindsTo"
         # get the vlan's setting object
         $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"

         # get the current trunk list and add the new vlan id into it.
         # one thing additionally we could do here, which the Hyper-V UI does is clean up
         # the old AccessVlan id of the port from the trunk list. But, we can't just remove the
         # old AccessVlan from the trunklist, because another port might be using the same vlan id.
         # We would have to enumerate all of the ports on the switch and build a new trunk list.
         # For the purposes of this script, don't worry about cleaning up old vlan id' from the trunk list.
         $trunkList = $vlanSetting.TrunkedVLANList
         if ($trunkList -notcontains $vlanid)
         {
            $trunkList = $trunkList + $vlanId
            $vlanSetting.TrunkedVLANList = $trunkList
            $result = $vlanSetting.Put()
         }
         # set the vlan mode into trunking mode.
         if ($vlan.DesiredEndpointMode -ne 5)
         {
            $vlan.DesiredEndpointMode = 5
            $result = $vlan.Put()
         }
    }

    # Now that we have finished with the trunklist, set the vlan id of the original connected port.

    $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_BindsTo"
    $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"
    $vlanSetting.AccessVlan = $vlanId
    $vlanSetting.Put()

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V TV: How to Fix BIOS error “Hypervisor is not running…”

    • 0 Comments

    image

    In this 5 minute video Windows Server Technical Writer Felipe Ayora demonstrates how to change the BIOS settings on your computer to make the hypervisor run. NOTE: remember to completely power off your computer after making the changes to the BIOS. Some computers will not take the changes unless they are powered off and back on.

    This error (BIOS misconfig)  stalls many users.

  • TONYSO

    Hyper-V How To: Shut Down VMs using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for shutting down your VMs:

    # Shutdown a Virtual Machine (requires Integration Components)

    param(
        [string]$vmName = $(throw "Must specify virtual machine name")
    )

    # Get the VM by name and request state to change to Enabled
    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the associated Shutdown Component
    $shutdown = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_ShutdownComponent"

    # Initiate a forced shutdown with simple reason string, return resulting error code
    return $shutdown.InitiateShutdown($true,"System Maintenance")

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Delete Snapshot using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for deleting a VM snapshot:

    However BEFORE you go deleting snapshots, please read the Hyper-V Snapshot FAQ, and have a look at the Ben Armstrong Snapshot FAQ Video

    # Delete Virtual System Snapshot

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$vmSnapName = $(throw "Must specify snapshot name")
    )

    # Get the virtual machine by name
    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the setting data for the snapshot by name
    $snapshot = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData `
        -filter "SystemName='$($vm.Name)' and SettingType = 5 and ElementName = '$vmSnapName'”
    if($snapshot -eq $null -or $snapshot -is [array]){
        throw "Unable to find single snapshot with name `"$vmSnapName`""
    }
    # Get the management service and apply the snapshot
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.RemoveVirtualSystemSnapshot($snapshot)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Compact a VHD using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for compacting your VHDs:

    # Compact a VHD

    param(
        [string]$vhdPath = $(throw "Must specify complete VHD path, including extension")
    )

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject Msvm_ImageManagementService -namespace root\virtualization

    # Compact a Dynamic VHD
    $result = $ImageMgtService.CompactVirtualHardDisk($VHD_Path.ToString())

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Expand a VHD

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for expanding VHD:

    # Expand a VHD

    param(
        [string]$vhdPath = $(throw "Must specify full path for VHD"),
        [string]$vhdSize = $(throw "Must specify expansion to add to VHD (in MB)")
    )

    # Size in bytes
    $MB = [System.UInt64] $vhdSize*1024*1024

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject -class "Msvm_ImageManagementService" -namespace "root\virtualization"

    # Create the Dynamic VHD
    $result = $ImageMgtService.ExpandVirtualHardDisk($vhdPath,$MB)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Copy-VM

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for copying a VM:

    ################################################################################
    #
    #   Copyright ©2008 Microsoft Corporation.  All rights reserved.
    #
    #   File: Copy-Vm.ps1
    #
    #   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    #   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    #   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    #   PARTICULAR PURPOSE.
    #
    #   Copyright ©2008 Microsoft Corporation.  All rights reserved.
    #
    ################################################################################

    param
    (
        [string]$VmName = $(throw "VmName required"),
        [string]$Path = $(throw "Path required"),
        [string]$NewName = ""
    )

    #
    # Constants
    #
    $SilentlyContinue = [System.Management.Automation.ActionPreference]0

    #
    # Utility functions
    #

    # Processes the (possibly asynchronous) result of a method call on one
    # of Hyper-V's service objects, and return the resulting object, if any.
    function ProcessResult
    {
        param
        (
            [System.Management.ManagementBaseObject]$Result,
            [ScriptBlock]$ExtractScript = $null,
            [string]$ResultClass = ""
        )

        $RetObj = $null

        if ($Result.ReturnValue -eq 0)
        {
            if ($ExtractScript -ne $null)
            {
                $RetObj = [WMI] ($Result | Select-Object -inputObject $ExtractScript)
            }
        }
        else
        {
            if ($Result.ReturnValue -ne 4096)
            {
                throw $Result.ReturnValue
        }
            $Job = [WMI]$Result.Job
            while ($Job.JobState -eq 4)
            {
                Write-Progress $Job.Caption "% Complete" -PercentComplete $Job.PercentComplete
                Start-Sleep 1
                $Job.PSBase.Get()
            }

            if ($Job.JobState -ne 7)
            {
                throw $Job.ErrorDescription
            }

            Write-Progress $Job.Caption "Completed" -Completed $true

            if ($ResultClass -ne "")
            {
                $Query = "Associators of {$Job} Where ResultClass=$ResultClass AssocClass=Msvm_AffectedJobElement"
                $RetObj = Get-WmiObject -Namespace root\virtualization -Query $Query
        }
        }

        if ($RetObj -ne $null)
        {
        $RetObj
        }
    }

    #
    # Main script body
    #

    #Stop script exection on errors
    Set-Variable $ErrorActionPreference Stop

    # If no target name was specified, generate a generic one
    if ($NewName -eq "")
    {
        $NewName = "Copy of " + $VmName
    }

    # If we are going to display progress bars, clear the console window so that
    # we can see the progress bars more clearly,
    if ($ProgressPreference -ne $SilentlyContinue)
    {
        Clear-Host
        Write-Host "Copying `"$VmName`" to `"$NewName`"..."
    }

    # Get the service object
    $VmSvc = Get-WmiObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService

    # Find the virtual machine to copy.
    $Query = @"
    Select * From Msvm_ComputerSystem Where
        ElementName='$VmName' Or
        Name='$VmName'
    "@

    $SourceVm = Get-WmiObject -Namespace root\virtualization -Query $Query

    # Since the virtual machine name is not unique, we need to check for
    # multiples. If there is more than one, we'll return an error.
    $SourceCount = [int]0
    if ($SourceVm -ne $null)
    {
        $SourceCount = [int]($SourceVm | Measure-Object).Count
    }

    if ($SourceCount -eq 0)
    {
        throw "Virtual machine `"$VmName`" not found."
        return
    }
    elseif ($SourceCount -ne 1)
    {
        if ($ProgressPreference -ne $SilentlyContinue)
        {
            Write-Host "The name `"$VmName`" has been given to multiple virtual machines. Specify the source virtual machine by ID instead. The IDs for virtual machines with this name are listed below."
            $SourceVm | `
                Select-Object @{Name="ID";Expression={$_.Name}},@{Name="Name";Expression={$_.ElementName}} | `
                Format-Table -AutoSize
        }
        throw "The name `"$VmName`" has been given to multiple virtual machines."
    }

    # Export the virtual machine
    $Result = $VmSvc.ExportVirtualSystem($SourceVm, $true, $Path)
    $Temp = ProcessResult $Result

    # Rename the export directory
    $CopyPath = (Join-Path $Path $VmName | Rename-Item -NewName $("Copy of " + $VmName) -PassThru)

    # Import the virtual machine
    $Result = $VmSvc.ImportVirtualSystem($CopyPath, $true)
    $CopyVm = ProcessResult $Result {throw "Unexpected error."} Msvm_ComputerSystem

    # Rename the copy virtual machine to "Copy of $VmName"
    $Query = @"
    Associators of {$CopyVm} Where
        ResultClass=Msvm_VirtualSystemSettingData
        AssocClass=Msvm_SettingsDefineState
    "@

    $CopyVssd = Get-WmiObject -Namespace root\virtualization -Query $Query
    $CopyVssd.ElementName = "Copy of " + $CopyVssd.ElementName

    $Result = $VmSvc.ModifyVirtualSystem($CopyVm, $CopyVssd.PSBase.GetText(1))
    $Temp = ProcessResult $Result {$_.ModifiedSettingData} Msvm_VirtualSystemSettingData

    # Update and return the copied virtual machine object
    $CopyVm.PSBase.Get()
    $CopyVm

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Add a Virtual NIC to a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for adding a virtual NIC to a VM:

    # Add a NIC (synthetic ethernet port) to a virtual machine

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$ethPortName = "New Network Adapter"
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Allocate the new ethernet port
    $allocationCapabilities = gwmi -namespace root\virtualization Msvm_AllocationCapabilities `
        -filter "ResourceType = 10 AND ResourceSubtype = 'Microsoft Synthetic Ethernet Port'"
    $allocationPath = $allocationCapabilities.__PATH.replace("\","\\")
    $default = gwmi -namespace root\virtualization Msvm_SettingsDefineCapabilities `
        -filter "ValueRange = 0 AND GroupComponent = '$allocationPath'"

    $synthEth = [wmi]$default.PartComponent
    $synthEth.ElementName = $ethPortName
    $newGuid = [System.Guid]::NewGuid().Guid
    $synthEth.VirtualSystemIdentifiers = @("{$newGuid}")

    # Attach the new NIC (ethernet port) to the virtual machine
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.AddVirtualSystemResources($vm,@($synthEth.GetText(1)))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Create a Virtual Switch using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for creating a virtual switch:

    # Create a Virtual Switch

    param(
        [string]$vsName = $(throw "Must specify virtual switch name")
    )

    # Get the Virtual Switch Management Service
    $vsms = gwmi -namespace root\virtualization Msvm_VirtualSwitchManagementService

    # Use CreateSwitch method to specify the name, friendly name, learnable addresses,
    # and authorization scope of the created switch (use "" for the root scope)
    $result = $vsms.CreateSwitch($vsName,$vsName,2048,"")
    if($result.ReturnValue -ne 0){
        throw "Error: $($result.ReturnValue)"
    }
    return ([wmi]$result.CreatedVirtualSwitch)

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Check Hypervisor Heartbeat using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for checking in the hypervisor is running on a Hyper-V server (host/parent partition):

    # Check if Hypervisor is running

    $hypervisor = gwmi –ErrorAction SilentlyContinue Win32_PerfRawData_HvStats_HyperVHypervisor
    return $hypervisor.Partitions -ge 1

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Add a PT Disk to A VM with a Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for adding a pass-through disk to a VM:

    # Add a pass-through disk to a VM

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [int]$ideNum = $(throw "Must specify IDE location to attach the pass-through disk"),
        [int]$lunNum = $(throw "Must specify LUN location to attach the pass-through disk")
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Disks available for pass-through are associated to the physical disk resource pool
    # (for this example, it is assumed there is only one disk available)
    $diskPool = gwmi -namespace root\virtualization Msvm_ResourcePool `
        -filter "ResourceType = 22 AND ResourceSubtype = 'Microsoft Physical Disk Drive'"
    $disk = gwmi -namespace root\virtualization `
        -query "Associators of {$diskPool} where ResultClass=Msvm_DiskDrive"

    # Get the virtual machine's setting data
    $vssd = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_VirtualSystemSettingData" |`
        where{$_.SettingType -eq 3}

    # Get IDE Controller
    $ide = gwmi -namespace root\virtualization `
        -query "Associators of {$vssd} where ResultClass=Msvm_ResourceAllocationSettingData" |`
        where{$_.ResourceType -eq 5 -and $_.Address -eq $ideNum}

    # Create a new Hard Disk Resource Allocation object for a disk at specified lun,
    # and connect it to the server disk
    $allocationCapabilities = gwmi -namespace root\virtualization Msvm_AllocationCapabilities `
        -filter "ResourceType = 22 AND ResourceSubtype = 'Microsoft Physical Disk Drive'"
    $allocationPath = $allocationCapabilities.__PATH.replace("\","\\")
    $default = gwmi -namespace root\virtualization Msvm_SettingsDefineCapabilities `
        -filter "ValueRange = 0 AND GroupComponent = '$allocationPath'"

    $hardDisk = [wmi]$default.PartComponent
    $hardDisk.Address = $lunNum
    $hardDisk.HostResource = @($disk.__PATH)
    $hardDisk.Parent = $ide.__PATH

    # Attach the new Hard Disk to the virtual machine
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.AddVirtualSystemResources($vm,@($hardDisk.GetText(1)))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    Useful? Want to see more sample scripts? Leave feedback.

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx 

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Remote Server Administration Tools for Windows 7 Released

    • 0 Comments

    Hyper-V R2 users have been waiting for the remote tools, released today as RSAT Tools for Windows 7 at: http://www.microsoft.com/downloads/details.aspx?FamilyID=7d2f6ad7-656b-4313-a005-4e344e43997d&displaylang=en

  • TONYSO

    Hyper-V How To: Convert a VHD using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for converting your VHDs:

    # Convert a VHD

    param(
        [string]$vhdPath = $(throw "Must specify full VHD path, including extension"),
        [string]$destPath = $(throw "Must specify full path of destination VHD, including extension"),
        [switch]$Fixed,
        [switch]$Dynamic
    )

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject Msvm_ImageManagementService -namespace root\virtualization

    # Convert the VHD
    if($Dynamic){
        $result = $ImageMgtService.ConvertVirtualHardDisk($vhdPath,$destPath,3)
    }else if($Fixed){
        $result = $ImageMgtService.ConvertVirtualHardDisk($vhdPath,$destPath,2)
    }else{
        throw "Must specify type of vhd to covert to with either the -Fixed or -Dynamic flag"
    }

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Check if ICs are Current using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for checking the integration services/integration components to see if they are current in your VMs:

    # Test if the IC version is up to date

    param(
        [string]$vmName = $(throw "Must specify virtual machine name")
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the associated KVP Exchange component
    $kvp = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_KvpExchangeComponent"

    # Pull the Guest Intrinsic Exchange Items from XML into a hash
    $kvpHash = @{}
    if($kvp.GuestIntrinsicExchangeItems){
        ([xml]("<xml>"+$kvp.GuestInstrinsicExchangeItems+"</xml>")).xml.instance | `
            foreach{$kvphash.add($_.property[4].value,$_.property[1].value)}
    }

    # Save the guest's version
    $icVersionGuest = $kvpHash.IntegrationServicesVersion

    # Save the host's version
    $icVersionHost = (ls 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestInstaller').`
        GetValue("Microsoft-Hyper-V-Guest-Installer-Win60-Package")

    return -not $icVersionGuest -lt $icVersionHost

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Delete a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for deleting a VM:

    # Delete a VM

    param(
        [string]$VMName = $(throw "Must specify name of virtual machine to delete")
    )
    #Obtain the VM object that we are going to destroy
    $query = "SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" + $VMName + "'"
    $VM = gwmi -query $query -namespace "root\virtualization"
    #obtain the VirtualSystemManagementService class
    $VSMgtService = get-wmiobject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization"
    #Destroy the virtual computer system.
    $result = $VSMgtService.DestroyVirtualSystem($VM)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Map your Virtual Network Settings using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for getting a mapping your virtual network settings:

    # Navigate Network Topology to determine Virtual Switch type
    # ie: Internal, External, External-Shared, or Private

    # Prompt for the Hyper-V Server to use
    $HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
    write-host
    # Get the list of all available network switches
    $query = "Select * From Msvm_VirtualSwitch"
    $VirtualSwitches = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
    # Iterate over each virtual switch
    foreach ($VirtualSwitch in $VirtualSwitches)      
       { 
       # Initialize variables for counting number of internal and external ports per switch
       $InternalPortCount = 0
       $ExternalPortCount = 0
       # Get the Switch ports on the virtual switch 
       $query = "Associators of {$VirtualSwitch} where ResultClass=CIM_SwitchPort"
       $switchPorts = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
       # A VM only switch with no VMs connected will return null
       if ($switchPorts -ne $null)
          {
          # Iterate over each switch port
          foreach ($switchPort in @($switchPorts))      
             {
             # Get the Msvm_SwitchLANEndpoint associated with the switch port
             $query = "Associators of {$switchPort} where ResultClass=Msvm_SwitchLANEndpoint"
             $SwitchLANEndpoint = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
             # If there is no active connection on the switch port the results will be null
             if ($SwitchLANEndpoint -ne $null)
                {
                # Get the CIM_EthernetPort for the Msvm_SwitchLANEndpoint
                $query = "Associators of {$SwitchLANEndpoint} where ResultClass=CIM_EthernetPort"
                $EthernetPort = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
                # Check to see if the associated Ethernet port is an internal port
                if ($EthernetPort.__CLASS -eq "Msvm_InternalEthernetPort")
                   {
                   $InternalPortCount = $InternalPortCount + 1
                   }
                # Check to see if the associated Ethernet port is an external port
                if ($EthernetPort.__CLASS -eq "Msvm_ExternalEthernetPort")
                   {
                   $ExternalPortCount = $ExternalPortCount + 1
                   }
                }
             }
          }
       switch ($InternalPortCount)
          {
          0
             {
             switch ($ExternalPortCount)
                {
                0 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is a virtual machine only virtual network."}
                1 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an external-only virtual network."}
                default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
                }
             }
          1
             {
             switch ($ExternalPortCount)
                {
                0 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an internal virtual network."}
                1 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an external virtual network."}
                default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
                }
             }
          default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
          }
       write-host $output
       }

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Connect a Virtual Switch to a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for connecting a virtual switch to a VM:

    # Connect Virtual Switch to VM

    param(
        [string]$vsName = $(throw "Must specify virtual switch name"),
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$switchPortName = [guid]::NewGuid().guid
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    # Find the NIC from the virtual system setting data (assuming there is only one)
    $vssd = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass = Msvm_VirtualSystemSettingData" |`
        where{$_.SettingType -eq 3}
    $synthEth = gwmi -namespace root\virtualization `
        -query "Associators of {$vssd} where ResultClass = Msvm_SyntheticEthernetPortSettingData"

    # Get the virtual switch (assuming only one in the system)
    $vSwitch = gwmi -namespace root\virtualization Msvm_VirtualSwitch -filter "ElementName = '$vsName'"

    # Get the virtual switch and virtual system services
    $vsms = gwmi -namespace root\virtualization Msvm_VirtualSwitchManagementService
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    # Use the switch service to create a new switch port
    $result = $vsms.CreateSwitchPort($vSwitch, $switchPortName, "VM Switch Port", "")
    if($result.ReturnValue -ne 0){
        return $result.ReturnValue
    }
    $switchPort = [wmi]$result.CreatedSwitchPort

    # Set the NIC (synthetic ethernet port) connection to the switch port, and
    # then modify the virtual system
    $synthEth.Connection = @($switchPort.__PATH)
    $result = $vmms.ModifyVirtualSystemResources($vm,@($synthEth.GetText(1)))
    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Set Up Multi-site Clustering

    • 0 Comments

    Courtesy of a colleague, here are some handy resources for reading up on how to set up a multi-site cluster:

  • TONYSO

    Hyper-V: Everything you always wanted to know about clustering* but were afraid to ask

    • 0 Comments

    My teenage daughter never tires of reminding me how often I show my age. The punning title of this blog is no exception.

    imageHowever, that should not take away from the awesomeness of the Clustering Team Blog post that lists 300+ useful documents, guides, information and utilities.

    My favorites of course are on Hyper-V:

    I prefer mine with PowerShell:

    and a side of tools:

    Utility: ClusPrep: Cluster Configuration Validation Wizard (2003)

    Utility: Failover Cluster Management Pack for Operations Manager 2007

    Utility: File Server Migration Toolkit (FSMT) (2008)

    Utility: Microsoft iSCSI Target Software available to the public!

    Utility: NLB Management Pack for SCOM 2007 Released

    Utility: RSAT - Remote Server Administration Tools (2008)

    Utility: RSAT – Remote Server Administration Tools (2008 R2)

Page 1 of 3 (58 items) 123
  • TONYSO

    Hyper-V How To: Detect if you are inside a VM

    • 1 Comments

    Sometimes, when troubleshooting or for forensic reasons, you may have to determine if an application is running inside a virtual machine. John Kelbley, co-author of Windows Server 2008 Hyper-V : Insiders Guide to Microsoft's Hypervisor, shares how.

    One (relatively) simple way to detect key virtualization information is via WMI / WBEM.  You can use the root\CIM2 namespace and access  the Baseboard class (full of interesting BIOS information) to get a description of the "physical" system.  This class often includes information about the motherboard and chassis  - manufacture, model, serial number, other.   You can run the following VBS to get this info.

    On Error Resume Next

    Const wbemFlagReturnImmediately = &h10
    Const wbemFlagForwardOnly = &h20

    arrComputers = Array(".")
    For Each strComputer In arrComputers
       WScript.Echo
       WScript.Echo "=========================================="
       WScript.Echo "Computer: " & strComputer
       WScript.Echo "=========================================="

       Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
       Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", _
                                              wbemFlagReturnImmediately + wbemFlagForwardOnly)

       For Each objItem In colItems
          WScript.Echo "Caption: " & objItem.Caption
          strConfigOptions = Join(objItem.ConfigOptions, ",")
             WScript.Echo "ConfigOptions: " & strConfigOptions
          WScript.Echo "   CreationClassName: " & objItem.CreationClassName
          WScript.Echo "         Description: " & objItem.Description
          WScript.Echo "        HostingBoard: " & objItem.HostingBoard
          WScript.Echo "         InstallDate: " & WMIDateStringToDate(objItem.InstallDate)
          WScript.Echo "        Manufacturer: " & objItem.Manufacturer
          WScript.Echo "               Model: " & objItem.Model
          WScript.Echo "                Name: " & objItem.Name
          WScript.Echo "OtherIdentifyingInfo: " & objItem.OtherIdentifyingInfo
          WScript.Echo "          PartNumber: " & objItem.PartNumber
          WScript.Echo "             Product: " & objItem.Product
          WScript.Echo "        SerialNumber: " & objItem.SerialNumber
          WScript.Echo "                 SKU: " & objItem.SKU
          WScript.Echo "              Status: " & objItem.Status
          WScript.Echo "                 Tag: " & objItem.Tag
          WScript.Echo "             Version: " & objItem.Version
          WScript.Echo
       Next
    Next

    Function WMIDateStringToDate(dtmDate)
    WScript.Echo dtm:
        WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _
        Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
        & " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
    End Function

    Here is a screen capture of the script results for a physical system running Windows Server 2008. 

    image

    NOTE the motherboard was manufactured by Intel  (model DG45ID).

    Running the same script in a virtual machine returns similar information:

    image

    NOTE On the virtual machine, the "motherboard" appears to be made by Microsoft (we don't make motherboards!) and is of a virtual type.

    The version number shown reflects the version of Hyper-V (Server 2008 RTM), and the Serial Number matches that found in the VM configuration file (XML file on the physical host).

    The Perl script version for this is:

    use strict;
    use Win32::OLE('in');

    use constant wbemFlagReturnImmediately => 0x10;
    use constant wbemFlagForwardOnly => 0x20;

    my @computers = (".");
    foreach my $computer (@computers) {
       print "\n";
       print "==========================================\n";
       print "Computer: $computer\n";
       print "==========================================\n";

       my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n";
       my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL",
                      wbemFlagReturnImmediately | wbemFlagForwardOnly);

       foreach my $objItem (in $colItems) {
          print "          Caption: $objItem->{Caption}\n";
          print "       ConfigOptions: " . join(",", (in $objItem->{ConfigOptions})) . "\n";
          print "   CreationClassName: $objItem->{CreationClassName}\n";
          print "         Description: $objItem->{Description}\n";
          print "        HostingBoard: $objItem->{HostingBoard}\n";
          print "         InstallDate: $objItem->{InstallDate}\n";
          print "        Manufacturer: $objItem->{Manufacturer}\n";
          print "               Model: $objItem->{Model}\n";
          print "                Name: $objItem->{Name}\n";
          print "OtherIdentifyingInfo: $objItem->{OtherIdentifyingInfo}\n";
          print "             Product: $objItem->{Product}\n";
          print "        SerialNumber: $objItem->{SerialNumber}\n";
          print "                 SKU: $objItem->{SKU}\n";
          print "              Status: $objItem->{Status}\n";
          print "                 Tag: $objItem->{Tag}\n";
          print "             Version: $objItem->{Version}\n";
          print "\n";
       }
    }sub WMIDateStringToDate(strDate)
    {
       return "blah";
    }

    For additional reference, within Windows I could also access  the same information in a single command line (in Windows XP or newer) by typing  the following:

         wmic baseboard get manufacturer, product, Serialnumber, version

    image

    For info on how to use Hper-V PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

    And buy John(et al)’s book!

    image

    Update: John's blogging now and has an updated method to detect the hypervisor: http://blogs.technet.com/enterprise_admin/archive/2009/10/20/detecting-the-virtualization-layer-from-within-a-guest-child-instance.aspx

  • TONYSO

    Hyper-V R2 How To: Move a VM + storage + snapshots

    • 0 Comments

    Want to move a VM from server A to server B along with its associated storage and snapshots in R2? Snapshots are associated with the VMs and not the VHD files. You should explore import/export. Soumya’s written a series of blogposts to get you started:

    http://blogs.technet.com/virtualization/archive/2009/05/20/hyper-v-r2-import-export-part-1-the-case-for-new-import-export-functionality.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/21/hyper-v-r2-import-export-part-2-the-new-import-export-apis.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/22/hyper-v-r2-import-export-part-3-the-ui.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/27/hyper-v-r2-import-export-part-4-export-code-sample.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/28/hyper-v-r2-import-export-part-5-import-code-sample.aspx

    http://blogs.technet.com/virtualization/archive/2009/05/29/hyper-v-r2-import-export-part-6-so-what-happened-to-configuration-only-export.aspx

    Ben blogged about V1 (also called R1 now by some folks…) import/export: 
    http://blogs.msdn.com/virtual_pc_guy/archive/2008/08/26/hyper-v-export-import-part-1.aspx
    http://blogs.msdn.com/virtual_pc_guy/archive/2008/08/27/hyper-v-export-import-part-2.aspx

  • TONYSO

    Hyper-V How To: Modify VM VLAN IDs for Server Core using Script

    • 0 Comments

    Need to remotely set the VLAN IDs on your server core installation? Some friends on the Hyper-V team put together a powershell 2.0 script for setting vlan id which you could run on the server core directly (rename the extension of the script to .ps1). The script accepts a vm name, and vlan id, finds the first connected network adapter of that vm and sets it to that vlan id.

    ################################################################################
    #
    #   Copyright ©2009 Microsoft Corporation.  All rights reserved.
    #
    #   File: modify-vlan.ps1
    #
    #   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    #   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    #   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    #   PARTICULAR PURPOSE.
    #
    #   Copyright ©2009 Microsoft Corporation.  All rights reserved.
    #
    ################################################################################

    param(
        $vmName = $(throw "Must supply a virtual machine name"),
        $vlanId = $(throw "Must supply  vlan id"),
        $computer = "."
    )

    $ns = "root\virtualization"

    # get the computer system
    $vm = gwmi -namespace $ns -computerName $computer Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    if ($vm -eq $null)
    {
       "No virtual machine with name '$vmName'"
       return
    }

    # get its related vssd
    $vssd = gwmi -namespace $ns -computerName $computer -query "associators of {$vm} where AssocClass=Msvm_SettingsDefineState"

    # get its synthetic and enumlated NICs
    $nics = gwmi -namespace $ns -computerName $computer -query "associators of {$vssd} where AssocClass=Msvm_VirtualSystemSettingDataComponent" |
        where {$_.ResourceType -eq 10 -and ($_.ResourceSubType -eq 'Microsoft Synthetic Ethernet Port' -or
                                            $_.ResourceSubType -eq 'Microsoft Emulated Ethernet Port')}

    if ($nics -eq $null)
    {
       # vm does not have any NICs.
       "Virtual machine '$vmName' does not have any NICs"
       return

    # Find the first nic which has a connection
    $nic = $nics | where {$_.Connection -ne $null} | select-object -first 1

    if ($nic -eq $null)
    {
        "None of the NICs on virtual machine '$vmName' are connected"
        return
    }

    # get the connected switch port.
    $connectedPort = [wmi]$nic.Connection[0]

    # need to set the external trunk list of the external port on this same switch
    # to include this vlan id, else traffic won't get through.

    # first get its switch.
    $switch = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_HostedAccessPoint"

    # enumerate all of its ports. Find the port which is externally connected.
    $ports = gwmi -namespace $ns -computerName $computer -query "associators of {$switch} where ResultClass=Msvm_SwitchPort"
    $externalPort = $null

    foreach ($p in $ports)
    {
       $switchLanEndpoint = gwmi -namespace $ns -computerName $computer -query "associators of {$p} where ResultClass=Msvm_SwitchLanEndpoint"
       if ($switchLanEndpoint -ne $null)
       {
          $externalEthernetPort = gwmi -namespace $ns -computerName $computer -query "associators of {$switchLanEndpoint} where resultclass=Msvm_ExternalEthernetPort"
          if ($externalEthernetPort -ne $null)
          {
             # we got it, we found the switch port connected to the external
             # port, save it and break out of the loop.
             $externalPort = $p
             break
          }
       }
    }

    if ($externalPort -ne $null)
    {
         # get the port's VlanEndpoint
         $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$externalPort} where AssocClass=Msvm_BindsTo"
         # get the vlan's setting object
         $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"

         # get the current trunk list and add the new vlan id into it.
         # one thing additionally we could do here, which the Hyper-V UI does is clean up
         # the old AccessVlan id of the port from the trunk list. But, we can't just remove the
         # old AccessVlan from the trunklist, because another port might be using the same vlan id.
         # We would have to enumerate all of the ports on the switch and build a new trunk list.
         # For the purposes of this script, don't worry about cleaning up old vlan id' from the trunk list.
         $trunkList = $vlanSetting.TrunkedVLANList
         if ($trunkList -notcontains $vlanid)
         {
            $trunkList = $trunkList + $vlanId
            $vlanSetting.TrunkedVLANList = $trunkList
            $result = $vlanSetting.Put()
         }
         # set the vlan mode into trunking mode.
         if ($vlan.DesiredEndpointMode -ne 5)
         {
            $vlan.DesiredEndpointMode = 5
            $result = $vlan.Put()
         }
    }

    # Now that we have finished with the trunklist, set the vlan id of the original connected port.

    $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_BindsTo"
    $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"
    $vlanSetting.AccessVlan = $vlanId
    $result = $vlanSetting.Put()

    ################################################################################
    #
    #   .SYNOPSIS
    #
    #       Sets the vlan id of the first connected NIC on a virtual machine.
    #      
    #
    #   .DESCRIPTION
    #
    #       Finds the first connected NIC of a virtual machine and sets up its VLAN
    #       settings in the same manner as the Hyper-V UI. First it checks to see if
    #       the NIC is connected to an external network, and if so it adds the VLAN id
    #       to the trunking list, and sets the endpoint mode to trunking. This makes sure
    #       that traffic with that VLAN id from the external network goes through the switch.
    #       Next it sets up the Access VLAN of the virtual machine's NIC.
    #
    #   .PARAMETER VmName
    #
    #       The name of the virtual machine to modify. We will modify the first connected
    #       NIC we find on this virtual machine.
    #
    #   .PARAMETER VlanId
    #
    #       The vlan id to set.
    #
    #   .PARAMETER Computer
    #
    #       The host computer where $vmname resides.
    #
    #   .EXAMPLE
    #
    #       C:\PS> mount-vlan.ps1 foo 512
    #
    #
    ################################################################################

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Build a Virtualized Test Infrastructure

    • 0 Comments

    I recently had the opportunity to chat with Rodney Fournier, Senior PFE at Microsoft, about building and running a testing infrastructure with our virtualization and management products, including Hyper-V R2, SCVMM, Operations Manager, Configurations Manager, PowerShell, well…Rod works with the whole stack basically. You kind of have to work with the whole stack to get a good pre-production test, don’t you?

    Click on the image to hear the 10 minute audio podcast.

    NetworkMixThumbnail

    Some useful links if you are in the same situation:

     

  • TONYSO

    Hyper-V How To: Find the right Hyper-V Cmdlet

    • 1 Comments

    Jamesone’s excellent PowerShell Management Library for Hyper-V includes a Hyper-V cmdlet documentation PDF file that helps you  chunk all the things you can do with Hyper-V using PS, for example, the following list of cmdlets parsed by function:

    Admin functions not specific to Hyper-V

    • Test-Admin Tests if the Powershell session is privileged
    • Get-ScriptPath Returns the path to the script
    • Choose-List Allows the user to select a item from a list view
    • Choose-Tree Allows the user to select a item from a tree view
    • Out-Tree Prevents items in a tree view
    • New-zip Creates a new .ZIP archive file
    • Add-ZIPContent Adds files to a .ZIP archive file
    • Copy-ZIPContent Copies files to from .ZIP archive file
    • Get-ZIPContent Gives a lists of items in a ZIP archive file

    Conversion functions

    • Convert-DiskIDtoDrive Converts a drive ID number into it’s associated drive letters
    • Convert-VMState Converts th number for a VM state into the state’s name

    Functions for Hyper-V Servers

    • Get-VMHost Gets a list of Hosts running Hyper-V from Active directory

    Functions for checking WMI jobs created through Hyper-v

    • Test-WMIJob Checks on the state of job – can wait until it completes

    Virtual Machine

    • Choose-VM Allows the user to select VMs from a list
    • Get-VM Retuns WMI objects representing VMs
    • New-VM Creates a new VM
    • Set-VM Sers the properties of an Existing VM
    • Remove-VM Deletes a VM
    • Export-VM Invokes Hyper-Vs export process
    • Import-VM Invokes Hyper-Vs import process
    • Ping-VM Ping FQDNs found via KVP exchange integration component
    • Shutdown-VM Shuts down a VM’s OS cleanly via shutdown integration compoent
    • Start-VM Starts a VM or restarts a saved one
    • Stop-VM Powers down a VM without asking the OS to shutdown first
    • Suspend-VM Puts the VM into a saved state
    • Set-VMState Called by Start, stop and suspend VM set the requested states
    • Get-VmBackupScript Gets a script for backing up one or more VMs
    • Get-VMByMACaddress Discovers a VM from its MAC address
    • Get-VMJPEG Gets a JPEG image of the currect VM screen
    • Test-VMHeartBeat Tests the responses from the heartbeat integration component
    • Get-VMSettingData Returns the Setting data object for the VM
    • New-VMConnectSession Launches a VM connect session to a VM.

    VM Memory

    • Get-VMMemory Returns the amount of memory assigned to a VM
    • Set-VMMemory Sets the amount of memory assigned to a VM

    VM Processors

    • Get-VMCPUCount Gets the number and weighting of Processors assigned to VMs
    • Set-VMCPUCount Sets the number of Virtual Processors assigned to VMs
    • Get-VMProcessor Gets active Virtual Processors and their load data

    VM Disk Controllers

    • Get-VMDiskController Gets an IDE or SCSI controller (IDE controllers can’t be changed)
    • Add-VMSCSIcontroller Adds a synthetic SCSI controller to a VM
    • Remove-VMSCSIcontroller Removes a synthetic SCSI controller from a VM

    Hard disk and DVD drive objects

    • Add-VMDRIVE Connects a Harddisk drive or DVD drive to a controller
    • Remove-VMDRIVE removes a Hard disk drive or DVD drive from a controller
    • Get-VMDriveByController Gets the drives attached to a controller

    Hardisk and DVD disk Image object

    • Add-VMDisk Mounts a DVD or Hard disk image into a Drive
    • Get-VMDisk Gets a list of Virtual disk images in use
    • Set-VMDisk changes the disk image attached to a drive
    • Get-VMDiskByDrive Gets the VM disk image attached to a drive
    • Add-VMNewHardDisk Attaches a new virtual hard disk image to a new drive

    Virtual Hard disk image files

    • Get-VhdDefaultPath Gets the Default path Used by Hyper-v for VHD files
    • Get-VHDInfo Gets information about a VHD, such as its parent, size on disk
    • New-VHD Creates a new VHD file
    • Test-VHD Tests that a VHD can be mounted, and any parent is mountable
    • Compact-VHD Compacts a dynamic VHD file to save space on the host
    • Convert-VHD Changes a VHD from one type to another
    • Expand-VHD Expands the size of a virtual hard disk
    • Merge-VHD Merges the a child VHD with its parent to form a new disk
    • Mount-VHD Makes the VHD file appear as a local disk on the host
    • UnMount-VHD Reverses the mount process so the VHD can be used by a VM

    VM Floppy Disk

    • New-VFD Creates a new floppy disk image file
    • Add-VMFloppyDisk Mounts the Floppy disk in the floppy drive of a VM
    • Get-VMFloppyDisk Returns information about the mounted floppy disk
    • Remove-VMFloppyDisk Ejects any floppy disk from the drive of a VM

    Resource Allocation Settings data objects


    • New-VMRasd Creates objects used by other functions to describe VM components

    Serial Port Objects


    • Get-VMSerialPort Returns information about serial
    • Set-VMSerialPort Maps Serial ports on a VM to Named Pipes

    Ethernet Cards

    • Add-VMNic Adds a Nic to a VM
    • Choose-VMNic Allows the user to select a NIC attached to a virtual machine
    • Get-VMNic Returns information about network cards
    • Remove-VMNic Removes a NIC from a VM
    • Set-VMNICAddress Sets the MAC address for a NIC
    • Set-VMNICSwitch Connects a NIC to a virtual Switch
    • Get-VMNicport Gets the Switch port attached to a NIC
    • Get-VMnicSwitch Returns the Switch a NIC is connected to

    Ethernet Switches

    • Choose-VMExternalEthernet Allows the user to choose a host network card
    • New-VMExternalSwitch Creates a Virtual Switch connect to a host network card
    • New-VMInternalSwitch Creates a Virtual Switch accessible to VMs and the Host
    • New-VMPrivateSwitch Creates a Virtual Switch accessible to VMs
    • Choose-VMSwitch Allows the user to choose a virtual switch
    • Get-VMSwitch Returns information about virtual switches
    • New-VMSwitchPort Defines a new port on a virtual switch

    Key value Pairs

    • Get-VMKVP Gets Key/value pair information sent to the Host by Virtual Machines
    • Add-VMKVP Adds a Key/value pair to the list sent to VMs by the host
    • Remove-VMKVP Removes a Key/value pair from the list sent to VMs by the host

    Snapshots

    • Apply-VMSnapshot Applies a snapshot to a VM
    • Choose-VMSnapshot Allows the user to choose a snapshot
    • Get-VMSnapshot Gets information about snapshots
    • Get-VMSnapshotTree Formats the view of Snapshots as a tree
    • New-VMSnapshot Creates a new snapshot of a VMRemove-VMSnapshot Deletes a snapshot or tree of snapshots
    • Rename-VMSnapshot Renames a snapshot
    • Update-VMSnapshot Deletes a snapshot, and creates a new one with same name

    Did I mention the Management Library is free-as-in-beer?

    Want to know more about James? See http://blogs.technet.com/tonyso/archive/2009/06/24/a-day-in-the-life-of-an-it-pro-evangelist-james-o-neill.aspx

    For more Hyper-V scripts, see the Official Scripting Guys Forum.

  • TONYSO

    Hyper-V How To: Create a VM using Script

    • 2 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for creating a VM:

    # Create a VM

    param(
        [string]$vmName = $(throw "Must supply a virtual machine name")
    )

    # Get a new instance of Msvm_VirtualSystemGlobalSettingData
    $vsgsdClass = [wmiclass]"root\virtualization:Msvm_VirtualSystemGlobalSettingData"
    $vsgsd = $vsgsdClass.CreateInstance()
    $vsgsd.ElementName = $vmName

    # Get the managment service and define the system from the embedded instance
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.DefineVirtualSystem($vsgsd.GetText(1))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Modify VLAN Settings using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for modifying hte VLAN settings on your VMs:

    # Modify VLAN setting for VM

    param(
        $vmName = $(throw "Must supply a virtual machine name"),
        $vlanId = $(throw "Must supply  vlan id"),
        $computer = "."
    )

    $ns = "root\virtualization"

    # get the computer system
    $vm = gwmi -namespace $ns -computerName $computer Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    if ($vm -eq $null)
    {
       "No virtual machine with name '$vmName'"
       return
    }

    # get its related vssd
    $vssd = gwmi -namespace $ns -computerName $computer -query "associators of {$vm} where AssocClass=Msvm_SettingsDefineState"

    # get its synthetic and enumlated NICs
    $nics = gwmi -namespace $ns -computerName $computer -query "associators of {$vssd} where AssocClass=Msvm_VirtualSystemSettingDataComponent" |
        where {$_.ResourceType -eq 10 -and ($_.ResourceSubType -eq 'Microsoft Synthetic Ethernet Port' -or
                                            $_.ResourceSubType -eq 'Microsoft Emulated Ethernet Port')}

    if ($nics -eq $null)
    {
       # vm does not have any NICs.
       "Virtual machine '$vmName' does not have any NICs"
       return

    # Find the first nic which has a connection
    $nic = $nics | where {$_.Connection -ne $null} | select-object -first 1

    if ($nic -eq $null)
    {
        "None of the NICs on virtual machine '$vmName' are connected"
        return
    }

    # get the connected switch port.
    $connectedPort = [wmi]$nic.Connection[0]

    # need to set the external trunk list of the external port on this same switch
    # to include this vlan id, else traffic won't get through.

    # first get its switch.
    $switch = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_HostedAccessPoint"

    # enumerate all of its ports. First the port which is externally connected.
    $ports = gwmi -namespace $ns -computerName $computer -query "associators of {$switch} where ResultClass=Msvm_SwitchPort"
    $externalPort = $null

    foreach ($p in $ports)
    {
       $switchLanEndpoint = gwmi -namespace $ns -computerName $computer -query "associators of {$p} where ResultClass=Msvm_SwitchLanEndpoint"
       if ($switchLanEndpoint -ne $null)
       {
          $externalEthernetPort = gwmi -namespace $ns -computerName $computer -query "associators of {$switchLanEndpoint} where resultclass=Msvm_ExternalEthernetPort"
          if ($externalEthernetPort -ne $null)
          {
             # we got it, we found the switch port connected to the external
             # port, save it and break out of the loop.
             $externalPort = $p
             break
          }
       }
    }

    if ($externalPort -ne $null)
    {
         # get the port's VlanEndpoint
         $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$externalPort} where AssocClass=Msvm_BindsTo"
         # get the vlan's setting object
         $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"

         # get the current trunk list and add the new vlan id into it.
         # one thing additionally we could do here, which the Hyper-V UI does is clean up
         # the old AccessVlan id of the port from the trunk list. But, we can't just remove the
         # old AccessVlan from the trunklist, because another port might be using the same vlan id.
         # We would have to enumerate all of the ports on the switch and build a new trunk list.
         # For the purposes of this script, don't worry about cleaning up old vlan id' from the trunk list.
         $trunkList = $vlanSetting.TrunkedVLANList
         if ($trunkList -notcontains $vlanid)
         {
            $trunkList = $trunkList + $vlanId
            $vlanSetting.TrunkedVLANList = $trunkList
            $result = $vlanSetting.Put()
         }
         # set the vlan mode into trunking mode.
         if ($vlan.DesiredEndpointMode -ne 5)
         {
            $vlan.DesiredEndpointMode = 5
            $result = $vlan.Put()
         }
    }

    # Now that we have finished with the trunklist, set the vlan id of the original connected port.

    $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_BindsTo"
    $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"
    $vlanSetting.AccessVlan = $vlanId
    $vlanSetting.Put()

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V TV: How to Fix BIOS error “Hypervisor is not running…”

    • 0 Comments

    image

    In this 5 minute video Windows Server Technical Writer Felipe Ayora demonstrates how to change the BIOS settings on your computer to make the hypervisor run. NOTE: remember to completely power off your computer after making the changes to the BIOS. Some computers will not take the changes unless they are powered off and back on.

    This error (BIOS misconfig)  stalls many users.

  • TONYSO

    Hyper-V How To: Shut Down VMs using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for shutting down your VMs:

    # Shutdown a Virtual Machine (requires Integration Components)

    param(
        [string]$vmName = $(throw "Must specify virtual machine name")
    )

    # Get the VM by name and request state to change to Enabled
    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the associated Shutdown Component
    $shutdown = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_ShutdownComponent"

    # Initiate a forced shutdown with simple reason string, return resulting error code
    return $shutdown.InitiateShutdown($true,"System Maintenance")

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Delete Snapshot using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for deleting a VM snapshot:

    However BEFORE you go deleting snapshots, please read the Hyper-V Snapshot FAQ, and have a look at the Ben Armstrong Snapshot FAQ Video

    # Delete Virtual System Snapshot

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$vmSnapName = $(throw "Must specify snapshot name")
    )

    # Get the virtual machine by name
    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the setting data for the snapshot by name
    $snapshot = get-wmiobject -namespace root\virtualization Msvm_VirtualSystemSettingData `
        -filter "SystemName='$($vm.Name)' and SettingType = 5 and ElementName = '$vmSnapName'”
    if($snapshot -eq $null -or $snapshot -is [array]){
        throw "Unable to find single snapshot with name `"$vmSnapName`""
    }
    # Get the management service and apply the snapshot
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.RemoveVirtualSystemSnapshot($snapshot)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Compact a VHD using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for compacting your VHDs:

    # Compact a VHD

    param(
        [string]$vhdPath = $(throw "Must specify complete VHD path, including extension")
    )

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject Msvm_ImageManagementService -namespace root\virtualization

    # Compact a Dynamic VHD
    $result = $ImageMgtService.CompactVirtualHardDisk($VHD_Path.ToString())

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Expand a VHD

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for expanding VHD:

    # Expand a VHD

    param(
        [string]$vhdPath = $(throw "Must specify full path for VHD"),
        [string]$vhdSize = $(throw "Must specify expansion to add to VHD (in MB)")
    )

    # Size in bytes
    $MB = [System.UInt64] $vhdSize*1024*1024

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject -class "Msvm_ImageManagementService" -namespace "root\virtualization"

    # Create the Dynamic VHD
    $result = $ImageMgtService.ExpandVirtualHardDisk($vhdPath,$MB)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Copy-VM

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for copying a VM:

    ################################################################################
    #
    #   Copyright ©2008 Microsoft Corporation.  All rights reserved.
    #
    #   File: Copy-Vm.ps1
    #
    #   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    #   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    #   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    #   PARTICULAR PURPOSE.
    #
    #   Copyright ©2008 Microsoft Corporation.  All rights reserved.
    #
    ################################################################################

    param
    (
        [string]$VmName = $(throw "VmName required"),
        [string]$Path = $(throw "Path required"),
        [string]$NewName = ""
    )

    #
    # Constants
    #
    $SilentlyContinue = [System.Management.Automation.ActionPreference]0

    #
    # Utility functions
    #

    # Processes the (possibly asynchronous) result of a method call on one
    # of Hyper-V's service objects, and return the resulting object, if any.
    function ProcessResult
    {
        param
        (
            [System.Management.ManagementBaseObject]$Result,
            [ScriptBlock]$ExtractScript = $null,
            [string]$ResultClass = ""
        )

        $RetObj = $null

        if ($Result.ReturnValue -eq 0)
        {
            if ($ExtractScript -ne $null)
            {
                $RetObj = [WMI] ($Result | Select-Object -inputObject $ExtractScript)
            }
        }
        else
        {
            if ($Result.ReturnValue -ne 4096)
            {
                throw $Result.ReturnValue
        }
            $Job = [WMI]$Result.Job
            while ($Job.JobState -eq 4)
            {
                Write-Progress $Job.Caption "% Complete" -PercentComplete $Job.PercentComplete
                Start-Sleep 1
                $Job.PSBase.Get()
            }

            if ($Job.JobState -ne 7)
            {
                throw $Job.ErrorDescription
            }

            Write-Progress $Job.Caption "Completed" -Completed $true

            if ($ResultClass -ne "")
            {
                $Query = "Associators of {$Job} Where ResultClass=$ResultClass AssocClass=Msvm_AffectedJobElement"
                $RetObj = Get-WmiObject -Namespace root\virtualization -Query $Query
        }
        }

        if ($RetObj -ne $null)
        {
        $RetObj
        }
    }

    #
    # Main script body
    #

    #Stop script exection on errors
    Set-Variable $ErrorActionPreference Stop

    # If no target name was specified, generate a generic one
    if ($NewName -eq "")
    {
        $NewName = "Copy of " + $VmName
    }

    # If we are going to display progress bars, clear the console window so that
    # we can see the progress bars more clearly,
    if ($ProgressPreference -ne $SilentlyContinue)
    {
        Clear-Host
        Write-Host "Copying `"$VmName`" to `"$NewName`"..."
    }

    # Get the service object
    $VmSvc = Get-WmiObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService

    # Find the virtual machine to copy.
    $Query = @"
    Select * From Msvm_ComputerSystem Where
        ElementName='$VmName' Or
        Name='$VmName'
    "@

    $SourceVm = Get-WmiObject -Namespace root\virtualization -Query $Query

    # Since the virtual machine name is not unique, we need to check for
    # multiples. If there is more than one, we'll return an error.
    $SourceCount = [int]0
    if ($SourceVm -ne $null)
    {
        $SourceCount = [int]($SourceVm | Measure-Object).Count
    }

    if ($SourceCount -eq 0)
    {
        throw "Virtual machine `"$VmName`" not found."
        return
    }
    elseif ($SourceCount -ne 1)
    {
        if ($ProgressPreference -ne $SilentlyContinue)
        {
            Write-Host "The name `"$VmName`" has been given to multiple virtual machines. Specify the source virtual machine by ID instead. The IDs for virtual machines with this name are listed below."
            $SourceVm | `
                Select-Object @{Name="ID";Expression={$_.Name}},@{Name="Name";Expression={$_.ElementName}} | `
                Format-Table -AutoSize
        }
        throw "The name `"$VmName`" has been given to multiple virtual machines."
    }

    # Export the virtual machine
    $Result = $VmSvc.ExportVirtualSystem($SourceVm, $true, $Path)
    $Temp = ProcessResult $Result

    # Rename the export directory
    $CopyPath = (Join-Path $Path $VmName | Rename-Item -NewName $("Copy of " + $VmName) -PassThru)

    # Import the virtual machine
    $Result = $VmSvc.ImportVirtualSystem($CopyPath, $true)
    $CopyVm = ProcessResult $Result {throw "Unexpected error."} Msvm_ComputerSystem

    # Rename the copy virtual machine to "Copy of $VmName"
    $Query = @"
    Associators of {$CopyVm} Where
        ResultClass=Msvm_VirtualSystemSettingData
        AssocClass=Msvm_SettingsDefineState
    "@

    $CopyVssd = Get-WmiObject -Namespace root\virtualization -Query $Query
    $CopyVssd.ElementName = "Copy of " + $CopyVssd.ElementName

    $Result = $VmSvc.ModifyVirtualSystem($CopyVm, $CopyVssd.PSBase.GetText(1))
    $Temp = ProcessResult $Result {$_.ModifiedSettingData} Msvm_VirtualSystemSettingData

    # Update and return the copied virtual machine object
    $CopyVm.PSBase.Get()
    $CopyVm

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Add a Virtual NIC to a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for adding a virtual NIC to a VM:

    # Add a NIC (synthetic ethernet port) to a virtual machine

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$ethPortName = "New Network Adapter"
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Allocate the new ethernet port
    $allocationCapabilities = gwmi -namespace root\virtualization Msvm_AllocationCapabilities `
        -filter "ResourceType = 10 AND ResourceSubtype = 'Microsoft Synthetic Ethernet Port'"
    $allocationPath = $allocationCapabilities.__PATH.replace("\","\\")
    $default = gwmi -namespace root\virtualization Msvm_SettingsDefineCapabilities `
        -filter "ValueRange = 0 AND GroupComponent = '$allocationPath'"

    $synthEth = [wmi]$default.PartComponent
    $synthEth.ElementName = $ethPortName
    $newGuid = [System.Guid]::NewGuid().Guid
    $synthEth.VirtualSystemIdentifiers = @("{$newGuid}")

    # Attach the new NIC (ethernet port) to the virtual machine
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.AddVirtualSystemResources($vm,@($synthEth.GetText(1)))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Create a Virtual Switch using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for creating a virtual switch:

    # Create a Virtual Switch

    param(
        [string]$vsName = $(throw "Must specify virtual switch name")
    )

    # Get the Virtual Switch Management Service
    $vsms = gwmi -namespace root\virtualization Msvm_VirtualSwitchManagementService

    # Use CreateSwitch method to specify the name, friendly name, learnable addresses,
    # and authorization scope of the created switch (use "" for the root scope)
    $result = $vsms.CreateSwitch($vsName,$vsName,2048,"")
    if($result.ReturnValue -ne 0){
        throw "Error: $($result.ReturnValue)"
    }
    return ([wmi]$result.CreatedVirtualSwitch)

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Check Hypervisor Heartbeat using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for checking in the hypervisor is running on a Hyper-V server (host/parent partition):

    # Check if Hypervisor is running

    $hypervisor = gwmi –ErrorAction SilentlyContinue Win32_PerfRawData_HvStats_HyperVHypervisor
    return $hypervisor.Partitions -ge 1

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Add a PT Disk to A VM with a Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for adding a pass-through disk to a VM:

    # Add a pass-through disk to a VM

    param(
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [int]$ideNum = $(throw "Must specify IDE location to attach the pass-through disk"),
        [int]$lunNum = $(throw "Must specify LUN location to attach the pass-through disk")
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Disks available for pass-through are associated to the physical disk resource pool
    # (for this example, it is assumed there is only one disk available)
    $diskPool = gwmi -namespace root\virtualization Msvm_ResourcePool `
        -filter "ResourceType = 22 AND ResourceSubtype = 'Microsoft Physical Disk Drive'"
    $disk = gwmi -namespace root\virtualization `
        -query "Associators of {$diskPool} where ResultClass=Msvm_DiskDrive"

    # Get the virtual machine's setting data
    $vssd = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_VirtualSystemSettingData" |`
        where{$_.SettingType -eq 3}

    # Get IDE Controller
    $ide = gwmi -namespace root\virtualization `
        -query "Associators of {$vssd} where ResultClass=Msvm_ResourceAllocationSettingData" |`
        where{$_.ResourceType -eq 5 -and $_.Address -eq $ideNum}

    # Create a new Hard Disk Resource Allocation object for a disk at specified lun,
    # and connect it to the server disk
    $allocationCapabilities = gwmi -namespace root\virtualization Msvm_AllocationCapabilities `
        -filter "ResourceType = 22 AND ResourceSubtype = 'Microsoft Physical Disk Drive'"
    $allocationPath = $allocationCapabilities.__PATH.replace("\","\\")
    $default = gwmi -namespace root\virtualization Msvm_SettingsDefineCapabilities `
        -filter "ValueRange = 0 AND GroupComponent = '$allocationPath'"

    $hardDisk = [wmi]$default.PartComponent
    $hardDisk.Address = $lunNum
    $hardDisk.HostResource = @($disk.__PATH)
    $hardDisk.Parent = $ide.__PATH

    # Attach the new Hard Disk to the virtual machine
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    $result = $vmms.AddVirtualSystemResources($vm,@($hardDisk.GetText(1)))

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    Useful? Want to see more sample scripts? Leave feedback.

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx 

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Remote Server Administration Tools for Windows 7 Released

    • 0 Comments

    Hyper-V R2 users have been waiting for the remote tools, released today as RSAT Tools for Windows 7 at: http://www.microsoft.com/downloads/details.aspx?FamilyID=7d2f6ad7-656b-4313-a005-4e344e43997d&displaylang=en

  • TONYSO

    Hyper-V How To: Convert a VHD using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for converting your VHDs:

    # Convert a VHD

    param(
        [string]$vhdPath = $(throw "Must specify full VHD path, including extension"),
        [string]$destPath = $(throw "Must specify full path of destination VHD, including extension"),
        [switch]$Fixed,
        [switch]$Dynamic
    )

    #obtain the Msvm_ImageManagementService class
    $ImageMgtService = get-wmiobject Msvm_ImageManagementService -namespace root\virtualization

    # Convert the VHD
    if($Dynamic){
        $result = $ImageMgtService.ConvertVirtualHardDisk($vhdPath,$destPath,3)
    }else if($Fixed){
        $result = $ImageMgtService.ConvertVirtualHardDisk($vhdPath,$destPath,2)
    }else{
        throw "Must specify type of vhd to covert to with either the -Fixed or -Dynamic flag"
    }

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Check if ICs are Current using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for checking the integration services/integration components to see if they are current in your VMs:

    # Test if the IC version is up to date

    param(
        [string]$vmName = $(throw "Must specify virtual machine name")
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName='$vmName'"

    # Get the associated KVP Exchange component
    $kvp = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass=Msvm_KvpExchangeComponent"

    # Pull the Guest Intrinsic Exchange Items from XML into a hash
    $kvpHash = @{}
    if($kvp.GuestIntrinsicExchangeItems){
        ([xml]("<xml>"+$kvp.GuestInstrinsicExchangeItems+"</xml>")).xml.instance | `
            foreach{$kvphash.add($_.property[4].value,$_.property[1].value)}
    }

    # Save the guest's version
    $icVersionGuest = $kvpHash.IntegrationServicesVersion

    # Save the host's version
    $icVersionHost = (ls 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestInstaller').`
        GetValue("Microsoft-Hyper-V-Guest-Installer-Win60-Package")

    return -not $icVersionGuest -lt $icVersionHost

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Delete a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for deleting a VM:

    # Delete a VM

    param(
        [string]$VMName = $(throw "Must specify name of virtual machine to delete")
    )
    #Obtain the VM object that we are going to destroy
    $query = "SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" + $VMName + "'"
    $VM = gwmi -query $query -namespace "root\virtualization"
    #obtain the VirtualSystemManagementService class
    $VSMgtService = get-wmiobject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization"
    #Destroy the virtual computer system.
    $result = $VSMgtService.DestroyVirtualSystem($VM)

    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

     

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download

  • TONYSO

    Hyper-V How To: Map your Virtual Network Settings using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for getting a mapping your virtual network settings:

    # Navigate Network Topology to determine Virtual Switch type
    # ie: Internal, External, External-Shared, or Private

    # Prompt for the Hyper-V Server to use
    $HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
    write-host
    # Get the list of all available network switches
    $query = "Select * From Msvm_VirtualSwitch"
    $VirtualSwitches = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
    # Iterate over each virtual switch
    foreach ($VirtualSwitch in $VirtualSwitches)      
       { 
       # Initialize variables for counting number of internal and external ports per switch
       $InternalPortCount = 0
       $ExternalPortCount = 0
       # Get the Switch ports on the virtual switch 
       $query = "Associators of {$VirtualSwitch} where ResultClass=CIM_SwitchPort"
       $switchPorts = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
       # A VM only switch with no VMs connected will return null
       if ($switchPorts -ne $null)
          {
          # Iterate over each switch port
          foreach ($switchPort in @($switchPorts))      
             {
             # Get the Msvm_SwitchLANEndpoint associated with the switch port
             $query = "Associators of {$switchPort} where ResultClass=Msvm_SwitchLANEndpoint"
             $SwitchLANEndpoint = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
             # If there is no active connection on the switch port the results will be null
             if ($SwitchLANEndpoint -ne $null)
                {
                # Get the CIM_EthernetPort for the Msvm_SwitchLANEndpoint
                $query = "Associators of {$SwitchLANEndpoint} where ResultClass=CIM_EthernetPort"
                $EthernetPort = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
                # Check to see if the associated Ethernet port is an internal port
                if ($EthernetPort.__CLASS -eq "Msvm_InternalEthernetPort")
                   {
                   $InternalPortCount = $InternalPortCount + 1
                   }
                # Check to see if the associated Ethernet port is an external port
                if ($EthernetPort.__CLASS -eq "Msvm_ExternalEthernetPort")
                   {
                   $ExternalPortCount = $ExternalPortCount + 1
                   }
                }
             }
          }
       switch ($InternalPortCount)
          {
          0
             {
             switch ($ExternalPortCount)
                {
                0 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is a virtual machine only virtual network."}
                1 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an external-only virtual network."}
                default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
                }
             }
          1
             {
             switch ($ExternalPortCount)
                {
                0 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an internal virtual network."}
                1 {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is an external virtual network."}
                default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
                }
             }
          default {$output = "The virtual switch '" + $VirtualSwitch.ElementName + "' is not a standard virtual network."}
          }
       write-host $output
       }

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Connect a Virtual Switch to a VM using Script

    • 0 Comments

    Some friends here on the Hyper-V team shared a PowerShell 2.0 script for connecting a virtual switch to a VM:

    # Connect Virtual Switch to VM

    param(
        [string]$vsName = $(throw "Must specify virtual switch name"),
        [string]$vmName = $(throw "Must specify virtual machine name"),
        [string]$switchPortName = [guid]::NewGuid().guid
    )

    $vm = gwmi -namespace root\virtualization Msvm_ComputerSystem -filter "ElementName = '$vmName'"

    # Find the NIC from the virtual system setting data (assuming there is only one)
    $vssd = gwmi -namespace root\virtualization `
        -query "Associators of {$vm} where ResultClass = Msvm_VirtualSystemSettingData" |`
        where{$_.SettingType -eq 3}
    $synthEth = gwmi -namespace root\virtualization `
        -query "Associators of {$vssd} where ResultClass = Msvm_SyntheticEthernetPortSettingData"

    # Get the virtual switch (assuming only one in the system)
    $vSwitch = gwmi -namespace root\virtualization Msvm_VirtualSwitch -filter "ElementName = '$vsName'"

    # Get the virtual switch and virtual system services
    $vsms = gwmi -namespace root\virtualization Msvm_VirtualSwitchManagementService
    $vmms = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService

    # Use the switch service to create a new switch port
    $result = $vsms.CreateSwitchPort($vSwitch, $switchPortName, "VM Switch Port", "")
    if($result.ReturnValue -ne 0){
        return $result.ReturnValue
    }
    $switchPort = [wmi]$result.CreatedSwitchPort

    # Set the NIC (synthetic ethernet port) connection to the switch port, and
    # then modify the virtual system
    $synthEth.Connection = @($switchPort.__PATH)
    $result = $vmms.ModifyVirtualSystemResources($vm,@($synthEth.GetText(1)))
    if($result.ReturnValue -eq 4096){
        # A Job was started, and can be tracked using its Msvm_Job instance
        $job = [wmi]$result.Job
        # Wait for job to finish
        while($job.jobstate -lt 7){$job.get()}
        # Return the Job's error code
        return $job.ErrorCode
    }
    # Otherwise, the method completed
    return $result.ReturnValue

    For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

    See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

    For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

  • TONYSO

    Hyper-V How To: Set Up Multi-site Clustering

    • 0 Comments

    Courtesy of a colleague, here are some handy resources for reading up on how to set up a multi-site cluster:

  • TONYSO

    Hyper-V: Everything you always wanted to know about clustering* but were afraid to ask

    • 0 Comments

    My teenage daughter never tires of reminding me how often I show my age. The punning title of this blog is no exception.

    imageHowever, that should not take away from the awesomeness of the Clustering Team Blog post that lists 300+ useful documents, guides, information and utilities.

    My favorites of course are on Hyper-V:

    I prefer mine with PowerShell:

    and a side of tools:

    Utility: ClusPrep: Cluster Configuration Validation Wizard (2003)

    Utility: Failover Cluster Management Pack for Operations Manager 2007

    Utility: File Server Migration Toolkit (FSMT) (2008)

    Utility: Microsoft iSCSI Target Software available to the public!

    Utility: NLB Management Pack for SCOM 2007 Released

    Utility: RSAT - Remote Server Administration Tools (2008)

    Utility: RSAT – Remote Server Administration Tools (2008 R2)

Page 1 of 3 (58 items) 123

August, 2009