Search code examples
powershellhyper-vhypervisor

What is the proper way to check if HyperV is running?


I am trying to write a powershell script to install and set up Hyper-V machines. The install seems to be ok, however, I get contradictory responses from the system. Basically, I use the (gcim Win32_ComputerSystem).HypervisorPresent to determine if HyperV is running.

It return False.

There is a similar class with the same member (gcim CIM_ComputerSystem).HypervisorPresent what is also returning False.

Also found this question How do you check to see if Hyper-V is enabled using PowerShell? and this state property is Enabled

Do I miss something? These queries aren't the same? Could you point if any of these are deprecated? Am I totally fooled, and Enabled means the system is capable to run HyperV, but actually it is not running?


Solution

  • CIM and WMI are a long tale but the short summary is that WMI is a Microsoft implementation of the OMI Standards defined by the DMTF, the Distributed Management Task Force, to come up with an industry wide standard. So, of course, creating one new standard resulted in a bunch of different implementations, which are basically their own standard.

    But otherwise CIM and WMI can be thought of as different gateways to the same information for Windows computers. Different doors to the same house. More on that history and the distinctions here.

    When I run the PowerShell commands you shared (either of them) on my machine with Hyper-V present, even when running as a standard, non-admin user, I get True back for both.

    You can also check to see if the BIOS firmware has virtualization enabled by looking in the CIM_Processor class.

    (Get-CimInstance win32_processor).VirtualizationFirmwareEnabled
    True
    

    You could also check to see if the Windows Feature is installed but that doesn't give you the full picture (what if the Windows feature is enabled in an image applied to a machine without virtualization components enabled in the BIOS, for instance.)

    [ADMIN] C:\>(Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All -Online).State
    Enabled
    

    Also, that technique 👆 requires admin permissions.

    Another way, and maybe the easiest is to check is to see if the Hyper-V Computer Service is running, which is needed for any VMs to launch, and can only run if everything else on the machine is done correctly to enable Hyper-V.

    Get-Service vmcompute
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  vmcompute          Hyper-V Host Compute Service
    

    We used to deploy servers with a MDT Task Sequence and enable Hyper-V along the way. It required reboots and special commands to run to apply the right bios settings. Then, we could enable the Windows Features, but those required two reboots, so it was quite tricky to handle with most imaging systems. Our final 'Sanity Check' was whether the Hyper-V compute service was running.