Hyper-V Resource Metering
In this video we explore the new resource metering features in Hyper-V 2012 and 2012R2. We talk about the structure and uses of resource metering and then we use PowerShell to implement resource metering on a clustered configuration.
Resource Metering Overview
Resource metering enables administrators to collect data about the resource usage of a VM or pool of VMs. This data is presented as average utilization over a time period. The time period is the time sense the metering was enabled, or sense the last metering reset. This data can be used for creating chargeback or show back models. As you will soon see, the data from resource metering is relatively simple. It is not meant to replace an enterprise performance monitoring tool such as System Center Operations Manager (SCOM). Resource metering is something that can only be configured via the PowerShell interface.
Resource metering allows you to collect information about the VM’s CPU, memory, network and storage utilization. The data collected is stored in the virtual machine’s configuration file. This means that the resource metering data will stay with the VM when it is migrated to another host or cluster node.
A hierarchy of resource pools can be created to group VMs. The groups can represent any logical collection that is meaningful in your environment. A VM’s resource may only belong to one resource group at a time. The resource group gets its totals from the data stored in the VM’s configuration files. As such, if a host has no VMs on it, its resource groups will not report any values and will be disabled. When creating a resource pool a ‘pool type’ must be defined. While it is possible to configure different names for each of the resource pool types, it may be easier to name all of the pools for a particular logical collection with the same name as we have done in the video. This makes collecting the data much easier, but is not a requirement.
PowerShell Command to Manage Resource Metering
Enable/Disable Resource Metering
Enable-VMResourceMetering
Disable-VMResourceMetering
Configure VM Resources for Metering
Set-VMProcessor
Set-VMHardDiskDrive
Set-VMMemory
Set-VMNetworkAdapter
Add-VMNetworkAdapterAcl
Remove-VMNetworkAdapterAcl
Creating/Removing Resource Pools
New-VMResourcePool
Set-VMResourcePool
Remove-VMResourcePool
Measuring VMs and Pools
Measure-VM
Measure-VMResourcePool
Reset-VMResourceMetering
Resource Metering Demo!
In the video we did a demo where we created resource pools called Pool1 on cluster HVC0 for our 3 VMs (App-1,2,3). We then gathered pool metering information from all of the nodes and displayed the aggregated data.
Here is the script that we used in the video:
ClusterResourcePoolFunctions.PS1
PowerShell Code for Resource Metering
###Demo 1 functions - Demo 1 Enable VM and Measure ###Show Cluster Resource Pool function Get-ClusterResourcePool { param ($Cluster = ".",$ResourcePool = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name Get-VMResourcePool -ComputerName $nodes -Name $ResourcePool } ### Enable Cluster Resource Metering VM function Enable-ClusterResourcePoolVM { param ($Cluster = ".", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name $VMS = Get-VM -ComputerName $Nodes -VMName $VMFilter -ErrorAction SilentlyContinue if($VMs){ #VMs found! $VMs |Enable-VMResourceMetering } else { "No Vms Match Filter" } } ### Measure Cluster Resource Pool VMs function Measure-ClusterResourcePoolVM{ param ($Cluster = ".", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name Measure-VM -ComputerName $nodes -Name $VMFilter -ErrorAction SilentlyContinue } #Demo 1 Enable VM and Measure Get-ClusterResourcePool -Cluster HVC0 Enable-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* start-vm -ComputerName HVC0N1 -Name App-2 Get-ClusterResourcePool -Cluster HVC0 Measure-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App-* stop-vm -ComputerName HVC0N1 -Name App-2 ###Demo 2 functions ###Create Cluster Resource Pool Function New-ClusterResourcePool { param ($Cluster = ".", $ResourcePool = "Pool1", $StoragePath = "NoneSupplied", $SwitchName="HVSwitch") $Nodes = (Get-ClusterNode -Cluster $Cluster).name New-VMResourcePool -ComputerName $Nodes -Name $ResourcePool -ResourcePoolType Ethernet,Processor,Memory If ($StoragePath -eq "NoneSupplied"){$StoragePath = (Get-ClusterSharedVolume -Cluster $cluster| select -ExpandProperty sharedVolumeInfo).friendlyvolumename} New-VMResourcePool -ComputerName $Nodes -Name $ResourcePool -ResourcePoolType VHD -Paths $StoragePath Get-VMSwitch -ComputerName $Nodes -Name $SwitchName| Add-VMSwitch -ResourcePoolName $ResourcePool } ### Set Cluster Resource Pool VM Assignment Function Set-ClusterResourcePoolVM { param ($Cluster = ".",$ResourcePool="Primordial", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name $VMS = Get-VM -ComputerName $Nodes -VMName $VMFilter -ErrorAction SilentlyContinue if($VMs){ #VMs found! foreach ($VM in $VMS) { Write-Debug "Setting resource pool $ResourcePool on VM $($VM.name)" $VM|Set-VMProcessor -ResourcePoolName $ResourcePool $VM|Set-VMMemory -ResourcePoolName $ResourcePool $VM|Get-VMNetworkAdapter| Set-VMNetworkAdapter -ResourcePoolName $ResourcePool $VM|Get-VMNetworkAdapter| Connect-VMNetworkAdapter -UseAutomaticConnection #ENABLES LIVE MIGRATION BETWEEN HOSTS IN CLUSTER $VM|Get-VMHardDiskDrive| Set-VMHardDiskDrive -ResourcePoolName $ResourcePool } } else {#no vms found! "No VMs match filter" } } ### Get Cluster Resource Pool VM Assignment Function Get-ClusterResourcePoolVM { param ($Cluster = ".", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name $VMS = Get-VM -ComputerName $Nodes -VMName $VMFilter -ErrorAction SilentlyContinue if($VMs){ #VMs found! foreach ($VM in $VMS) { Write-Debug "Getting resource pool info for VM $($VM.name)" $MyObj = ""| select VM, CPU, RAM, Disk, Network $MyObj.VM = $VM.name $Myobj.CPU = $vm| Get-VMProcessor|select -ExpandProperty ResourcePoolName $MyObj.RAM = $vm| Get-VMMemory|select -ExpandProperty ResourcePoolName $MyObj.Network = ($vm| Get-VMNetworkAdapter|select -ExpandProperty PoolName|select -Unique) -join "," $MyObj.Disk = ($vm| Get-VMHardDiskDrive|select -ExpandProperty PoolName|select -Unique) -join "," $MyObj } } else {#no vms found! "No VMs match filter" } } ### Measure Cluster Resource Pool function Measure-ClusterResourcePool { param ($Cluster = ".",$ResourcePool) $Nodes = (Get-ClusterNode -Cluster $Cluster).name $Pools = Get-VMResourcePool -ComputerName $Nodes | where-Object { $_.ResourceMeteringEnabled -eq "True"}|%{$_.name}| Select-Object -Unique foreach ($Pool in $Pools){ $MyObj = ""| select PoolName, AvgCPU, AvgRAM, TotalDisk, NetworkInbound, NetworkOutbound $MyObj.PoolName = $Pool $MyObj.AvgCPU = (Measure-VMResourcePool -ComputerName $nodes -name $pool -ResourcePoolType Processor ` -ErrorAction SilentlyContinue|Measure-Object -sum -Property AvgCPU).sum $MyObj.AvgRAM = (Measure-VMResourcePool -ComputerName $nodes -name $pool -ResourcePoolType Memory -ErrorAction SilentlyContinue|Measure-Object -sum -Property AvgRAM).sum $MyObj.TotalDisk = (Measure-VMResourcePool -ComputerName $nodes -name $pool -ResourcePoolType VHD -ErrorAction SilentlyContinue|Measure-Object -sum -Property TotalDisk).sum #Networking $networkGroup = Measure-VMResourcePool -computername $nodes -name $pool -ResourcePoolType Ethernet -ErrorAction SilentlyContinue | select -ExpandProperty NetworkMeteredTrafficReport|Group-Object -Property direction $MyObj.NetworkInbound = ($networkGroup|?{$_.name -eq "Inbound"}|select -ExpandProperty group|Measure-Object -Property TotalTraffic -Sum).sum $MyObj.NetworkOutbound = ($networkGroup|?{$_.name -eq "Outbound"}|select -ExpandProperty group|Measure-Object -Property TotalTraffic -Sum).sum $MyObj } } #Demo 2 Create, assign and measure pool New-ClusterResourcePool -Cluster HVC0 -ResourcePool Pool1 Get-ClusterResourcePool -Cluster HVC0 Get-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* | Format-Table -AutoSize Set-ClusterResourcePoolVM -Cluster HVC0 -ResourcePool pool1 -VMFilter App* Get-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* | Format-Table -AutoSize Start-VM -ComputerName (Get-ClusterNode -Cluster HVC0).name -Name App* Measure-ClusterResourcePool -Cluster HVC0 -ResourcePool pool1 ###Demo 3 functions ### Reset Cluster Resource Metering VM function Reset-ClusterResourcePoolVM { param ($Cluster = ".", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name $VMS = Get-VM -ComputerName $Nodes -VMName $VMFilter -ErrorAction SilentlyContinue if($VMs){ #VMs found! $VMs |Reset-VMResourceMetering } else { "No Vms Match Filter" } } ### Reset Cluster Resource Metering function Reset-ClusterResourcePool { param ($Cluster = ".",$ResourcePool="*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name Reset-VMResourceMetering -ComputerName $nodes -ResourcePoolName $ResourcePool -ErrorAction SilentlyContinue } #Demo 3 Reseting resource metering Stop-VM -ComputerName (Get-ClusterNode -Cluster HVC0).name -Name App* measure-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* Reset-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App-2 measure-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* Reset-ClusterResourcePool -Cluster HVC0 -ResourcePool pool1 measure-ClusterResourcePool -Cluster HVC0 -ResourcePool pool1 #Demo 4 functions ### Disable Cluster Resource Metering VM function Disable-ClusterResourcePoolVM { param ($Cluster = ".", $VMFilter = "*") $Nodes = (Get-ClusterNode -Cluster $Cluster).name $VMS = Get-VM -ComputerName $Nodes -VMName $VMFilter -ErrorAction SilentlyContinue if($VMs){ #VMs found! $VMs |Disable-VMResourceMetering } else { "No Vms Match Filter" } } ###Remove Cluster Resource Pool function Remove-ClusterResourcePool { param ($Cluster = ".",$ResourcePool) $Nodes = (Get-ClusterNode -Cluster $Cluster).name Remove-VMResourcePool -ComputerName $Nodes -Name $ResourcePool -ResourcePoolType Ethernet,Processor,Memory,VHD } #Demo 4 Remove resource pools Set-ClusterResourcePoolVM -Cluster HVC0 -ResourcePool "Primordial" -VMFilter App* Disable-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App* Remove-ClusterResourcePool -Cluster HVC0 -ResourcePool pool1 Get-ClusterResourcePool -Cluster HVC0 Get-ClusterResourcePoolVM -Cluster HVC0 -VMFilter App*| Format-Table * -AutoSize
Resources
TechNet: Introduction to Resource Metering
MSDN: Hyper-V Resource Metering Overview
Awesome job very good information thank you for taking the time to put this content together.
Great, I’m glad it helped you Tim!