Hyper-V PowerShell get disk usage and CPU usage (as seen by guest OS)

hyper-vvirtualization

I am writing a control-panel for Hyper-V (new to it; please forgive). Using this as a reference:[link]

Problem 1:I can only get the CPU usage as seen by the host-OS, which could be maximum 11-12% on a single-core guest. (I could divide this by [1/8] for a 8-core server and it would be approximate). On the guest, it would say '100%' for example. How can I get the guest's interpretation of CPU usage?

Problem 2: How can I get the disk-use as seen by the guest-OS from the server's PowerShell? I could take the size of the VHD file as seen by the host, but that's often not the same as the guest reports.

Problem 3: Is there a way to find the IP-address of the guest-OS if the network adapter is bridged?

Best Answer

I'll attempt it and I'll try to give some Hyper-V specific information here. I'm using Hyper-V Server 2012 as an example.

Problem 1: I can only get the CPU usage as seen by the host-OS

No, you can get the CPU usage however you want to get it. If you want to get the overall CPU usage of the guest OS as the guest itself sees it (an average of all its vCPUs,) Just do

$(Get-WMIObject -Computername $VM Win32_Processor).LoadPercentage

(Handling credentials if that VM happens to be in another domain is a separate issue but still entirely possible. If it's in the same domain as the machine you're taking the measurement from, the above command will "just work" via the magic of Kerberos domain authentication.) That isn't the only counter that will get you to the same place either, but that's as good an example as any.

You can of course get the load percentage of each "core" or vCPU individually on the guest OS if you wanted. Or if it's a Linux VM, just do top or something. Just be aware that VMs are not very good at calculating their own processor usage. They don't have the precision clocks that physical machines do for one thing. Even worse if the VM doesn't have the virtualization tools installed, as the integration tools are actual modifications to kernel code (called enlightenments in Windows) that give the guest VM better capabilities and compatibility as the guest is now aware that it's a VM.

Also be aware that the host operating system that has Hyper-V installed on it (aka the root partition) is actually just another guest VM itself, albeit a special guest with privileged access to the Hypervisor.

| Host OS | Guest VM | Guest VM | Guest VM | 
--------------------------------------------
                HYPERVISOR
--------------------------------------------
            Physical Hardware

There are special counters that are exposed to only the Host OS by the hypervisor, about it and all the other guest VMs running on the system.

There are seriously a ton of these Hyper-V specific performance counters and they let you slice up the data in practically every conceivable way.

Take the following counters for instance: \\HYPERVSERVER\Hyper-V Hypervisor Logical Processor\% Guest Run Time, % Hypervisor Run Time, % Total Run Time, etc. For each of those counters, you will find a separate instance for each VM currently on the system, as well as _Total, of course. You will see on your root partition (host OS,) that each VM on the system has its own user-mode VM worker process. (1 vmmp.exe per VM, plus 1 vmms.exe for the host.) In fact, if you are a hypervisor, you can think of each virtual machine on the system as a separate thread of execution subject to thread scheduling in the same way as if you had 10 instances of Skifree.exe running on your Windows system. But vmwp.exe is only part of the picture, so don't go thinking you can measure the CPU usage of that user-mode process on the host OS and call it good.

Notice that there is also a \\HYPERVSERVER\Hyper-V Hypervisor Root Virtual Processor\*, which gives the Logical Processor objects as the hypervisor has abstracted them from their associated physical processors and presented them to the Host OS. There are more counters; too many for me to go over. But you can read the descriptions of all the counters right in Perfmon.

There are some counters in the root\Virtualization namespace, and there are also some Hyper-V counters in the root\CIMv2 namespace. Here are some I just dug up:

PS C:\> Get-WmiObject -List | Where Name -Match Hyper | Select Name

Name
----
Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryBalancer
Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryBalancer
Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryVM
Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
Win32_PerfFormattedData_Counters_HyperVDynamicMemoryIntegrationService
Win32_PerfRawData_Counters_HyperVDynamicMemoryIntegrationService
Win32_PerfFormattedData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
Win32_PerfFormattedData_GmoPerfProvider_HyperVVMSaveSnapshotandRestore
Win32_PerfRawData_GmoPerfProvider_HyperVVMSaveSnapshotandRestore
Win32_PerfFormattedData_HvStats_HyperVHypervisor
Win32_PerfRawData_HvStats_HyperVHypervisor
Win32_PerfFormattedData_HvStats_HyperVHypervisorLogicalProcessor
Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
Win32_PerfFormattedData_HvStats_HyperVHypervisorPartition
Win32_PerfRawData_HvStats_HyperVHypervisorPartition
Win32_PerfFormattedData_HvStats_HyperVHypervisorRootPartition
Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
Win32_PerfFormattedData_HvStats_HyperVHypervisorRootVirtualProcessor
Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
Win32_PerfFormattedData_HvStats_HyperVHypervisorVirtualProcessor
Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
Win32_PerfFormattedData_HyperVReplicaStats_HyperVReplicaVM
Win32_PerfRawData_HyperVReplicaStats_HyperVReplicaVM
Win32_PerfFormattedData_IdePerfProvider_HyperVVirtualIDEControllerEmulated
Win32_PerfRawData_IdePerfProvider_HyperVVirtualIDEControllerEmulated
Win32_PerfFormattedData_NvspNicStats_HyperVVirtualNetworkAdapter
Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
Win32_PerfFormattedData_NvspPortStats_HyperVVirtualSwitchPort
Win32_PerfRawData_NvspPortStats_HyperVVirtualSwitchPort
Win32_PerfFormattedData_NvspSwitchProcStats_HyperVVirtualSwitchProcessor
Win32_PerfRawData_NvspSwitchProcStats_HyperVVirtualSwitchProcessor
Win32_PerfFormattedData_NvspSwitchStats_HyperVVirtualSwitch
Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
Win32_PerfFormattedData_RemotePerfProvider_HyperVVMRemoting
Win32_PerfRawData_RemotePerfProvider_HyperVVMRemoting
Win32_PerfFormattedData_StorageStats_HyperVVirtualStorageDevice
Win32_PerfRawData_StorageStats_HyperVVirtualStorageDevice
Win32_PerfFormattedData_VidPerfProvider_HyperVVMVidNumaNode
Win32_PerfRawData_VidPerfProvider_HyperVVMVidNumaNode
Win32_PerfFormattedData_VidPerfProvider_HyperVVMVidPartition
Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
Win32_PerfFormattedData_VmbusStats_HyperVVirtualMachineBus
Win32_PerfRawData_VmbusStats_HyperVVirtualMachineBus
Win32_PerfFormattedData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary

These counters are from the hypervisor itself, which is as close as you can get to the real hardware in this case. These counters will be much more accurate.

Problem 2: How can I get the disk-use as seen by the guest-OS from the server's PowerShell?

Get-WMIObject -Computername $VM Win32_LogicalDisk

As far as I know that is your best bet. Because the hypervisor doesn't care what the guest OS does with its storage. It only cares about the size of the associated .vhd's/.vhdx's, which as you pointed out isn't usually an accurate measure of how much data the VM thinks it has used on its logical drives.

Problem 3: Is there a way to find the IP-address of the guest-OS if the network adapter is bridged?

PS C:\> $(Get-WmiObject -ComputerName $VM win32_networkadapterConfiguration).IPAddress
192.168.1.5
fe80::858c:f47e:9bac:29eb
fd58:2c98:ee9c:279b::5

I think you're likely to have follow-up questions, so if you post them, I'll edit my post to try to answer them.

Edit:

To answer your question about getting the IP addresses of the virtual machines from the Hyper-V Host, without needing access to the VMs:

PS C:\> Get-VMNetworkAdapter *

Name            IsManagementOs VMName SwitchName             MacAddress   Status IPAddresses
----            -------------- ------ ----------             ----------   ------ -----------
Network Adapter False          WEB01  Hyper-V Virtual Switch 00155D015F00 {Ok}   {192.168.1.5, fe80::858c:f47e:9bac:...
Network Adapter False          ECA01  Hyper-V Virtual Switch 00155D015F05 {Ok}   {192.168.1.6, fe80::6890:cc44:2e50:...