How can I detect (.NET or Win32) if my application is running in a virtual machine?
-
I ran an app the other day, and it wouldn't run in a Virtual Machine.. . it said it couldn't. I was wondering how it knew. – Jason Jan 31 '09 at 06:06
-
7There are a number of things that don't work in VMs: some parts of MS SQL Server, the C# for devices emulator, and *gasp* Virtual PC/Server. Being able to plan for that in programs and scripts is valuable. – Jay Bazuzi Jan 31 '09 at 06:18
-
1...so if you have a dependency on something that doesn't work in some environments (i.e. VMs), then you should query that dependency to see if it's functional in the current environment. Or perhaps I missed your point? – reuben Jan 31 '09 at 22:38
12 Answers
This is what I use:
using (var searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
{
using (var items = searcher.Get())
{
foreach (var item in items)
{
string manufacturer = item["Manufacturer"].ToString().ToLower();
if ((manufacturer == "microsoft corporation" && item["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL"))
|| manufacturer.Contains("vmware")
|| item["Model"].ToString() == "VirtualBox")
{
return true;
}
}
}
}
return false;
Edit 2014-12-02: Updated code so that it no longer detects a Microsoft Surface Pro as a VM. Thanks to Erik Funkenbusch for pointing this out.
Edit 2017-06-29: Updated code so that it also checks the value of the HypervisorPresent
property.
Edit 2018-02-05: removed check for the HypervisorPresent
property since it's incorrect. This property could return true if running on the host O/S on a hyper-V server.

- 8,348
- 5
- 47
- 77
-
3Some quick tests looks like the test expression can be simplified (for some definition of 'simplified') to `item["Model"].ToString().ToLower().Contains("virtual")`. – Michael Burr Mar 13 '13 at 00:20
-
You can cast "items" as ``IEnumerable
`` like this: `var managementItems = items.OfType – Ben Clark-Robinson May 11 '14 at 03:34();` for use with `IEnumerable` extension methods. -
2I would think this code would detect Microsoft computer hardware as VM's, such as Surface Pro's. – Erik Funkenbusch Nov 29 '14 at 17:08
-
this code will not detect virtual machine run under Parallels Desktop, Xen and KVM – Dennis Aug 04 '16 at 07:10
-
@RobSiklos it works well but I create an api, how I can get the response that the call of the function of the api comes from a vm or physical machine ? – user10863293 Sep 17 '19 at 14:40
-
@user10863293 You would need to include that information in your response. That sounds like a different question though - you should create a new question to get the best help with this issue. – RobSiklos Sep 17 '19 at 18:24
-
1You can easily fake model in Virtualbox by running command `"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata "VM_NAME" "VBoxInternal/Devices/pcbios/0/Config/DmiSystemProduct" "Latitude E5400"` . And after this code won't going to detect. – Gray Programmerz Jul 12 '21 at 12:35
According to Virtual PC Guy's blog post "Detecting Microsoft virtual machines", you can use WMI to check the manufacturer of the motherboard. In PowerShell:
(gwmi Win32_BaseBoard).Manufacturer -eq "Microsoft Corporation"

- 45,157
- 15
- 111
- 168
-
25
-
5Also, as mentioned by commenter @ErikFunkenbusch on my answer to this question, this check will incorrectly identify the MS Surface Pro as a VM. – RobSiklos Dec 09 '14 at 14:54
-
2To be fair, for MS Virtual Machines, the Surface variety of products was released _after_ this answer was posted. – Allen Clark Copeland Jr Jan 15 '17 at 17:49
-
SO answers are not about being fair or unfair, they are about being helpful or not. This answer was undoubtedly useful at the time it was posted, but it is not anymore and RobSiklos (updated) answer should be marked as the correct one. Reputation points should be seen as an incentive to be helpful, not an ultimate goal to become a reputation millionaire ;) – Ama Dec 11 '19 at 12:01
This C function will detect VM Guest OS: (Tested on Windows, compiled with Visual Studio)
#include <intrin.h>
bool isGuestOSVM()
{
unsigned int cpuInfo[4];
__cpuid((int*)cpuInfo,1);
return ((cpuInfo[2] >> 31) & 1) == 1;
}

- 369
- 4
- 7
-
2To clarify, this piece of code uses the `cpuid` instruction to detect if the feature bit is set that indicates the code is running on a hypervisor. There is, of course, no requirement that an actual hypervisor always sets this bit, especially for software hypervisors. – Jeroen Mostert Sep 04 '17 at 11:13
-
2I would not use this. Tested false positive (Windows 10, VS) on my PC. I have virtualization support turned on in BIOS, but not running in VM, so it might be that (?). – Maros Macko May 06 '20 at 15:34
Jay Abuzi showed the solution in powershell. Here's the same as a c# function:
/// <summary>
/// Detect if this OS runs in a virtual machine
///
/// http://blogs.msdn.com/b/virtual_pc_guy/archive/2005/10/27/484479.aspx
///
/// Microsoft themselves say you can see that by looking at the motherboard via wmi
/// </summary>
/// <returns>false</returns> if it runs on a fysical machine
public bool DetectVirtualMachine()
{
bool result = false;
const string MICROSOFTCORPORATION ="microsoft corporation";
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_BaseBoard");
foreach (ManagementObject queryObj in searcher.Get())
{
result = queryObj["Manufacturer"].ToString().ToLower() == MICROSOFTCORPORATION.ToLower();
}
return result;
}
catch (ManagementException ex)
{
return result;
}
}

- 1,213
- 4
- 14
- 27
-
Sadly, this and similar techniques do not work in my W7 system running a VMWare ThinApp to test. The **queryObj.Properties** are identical in both environments. – Jesse Chisholm May 26 '13 at 16:06
-
2@JesseChisholm - not only that, but this will falsely report that Microsoft non-vm hardware is a VM, such as a Surface Pro. I'd suggest that you've got a setting wrong if your ThinApp is virtualizing the WMI data. – Erik Funkenbusch Nov 29 '14 at 17:29
-
@ErikFunkenbusch - The whole point of **virtualization** is so the code need not know or care whether it is live or virtual. So each VM manufacturer works very hard to make it impossible to know. So far, the only way I have found for _my_ app to know, is to have the VM execution pass in a command line parameter telling me I am running virtual. Sigh. – Jesse Chisholm Dec 16 '14 at 17:09
Remember you should not just check popular VM model,manufacturer name from wmi, You should also check difference between reality and virtualization.
VM don't have much features.
1) check-if-cpu-temperature-information-is-available
wmic /namespace:\\root\WMI path MSAcpi_ThermalZoneTemperature get CurrentTemperature
//On Real PC
//CurrentTemperature
//3147
//On VM
//Node - Admin
//Error:
//Description not supported
Tested on vmware,virtualbox,windows server,app.any.run sandbox.
2) Win32_PortConnector
Get-WmiObject Win32_PortConnector
//On Vm it is null
//On real pc it looks something like that
Tag : Port Connector 0
ConnectorType : {23, 3}
SerialNumber :
ExternalReferenceDesignator :
PortType : 2

- 466
- 10
- 29
-
the idea is good, but querying the temperatures requires admin rights; checking the port connector seems to work without – niyou May 18 '22 at 07:13
public static bool isVirtualMachine()
{
const string MICROSOFTCORPORATION = "microsoft corporation";
const string VMWARE = "vmware";
foreach (var item in new ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
string manufacturer = item["Manufacturer"].ToString().ToLower();
// Check the Manufacturer (eg: vmware, inc)
if (manufacturer.Contains(MICROSOFTCORPORATION) || manufacturer.Contains(VMWARE))
{
return true;
}
// Also, check the model (eg: VMware Virtual Platform)
if (item["Model"] != null)
{
string model = item["Model"].ToString().ToLower();
if (model.Contains(MICROSOFTCORPORATION) || model.Contains(VMWARE))
{
return true;
}
}
}
return false;
}

- 351
- 5
- 24
-
Sadly, this and similar techniques do not work in my W7 system running a VMWare ThinApp to test. The **queryObj.Properties** are identical in both environments. – Jesse Chisholm May 26 '13 at 16:07
For Lower level Tests I recommend looking at ScoopyNG [1]. It is a collection of known low-level, well working vm detection methods, albeit being a little dated.
If you really want to rely on other things, like installed tools (VM* Additions) , these are much easier to "fake".
This [2] Blog Post also has a pretty nice overview, from low level asm stuff, checking for specific DLLs, filepaths and registry keys to check.
[1] http://trapkit.de/research/vmm/scoopyng/index.html
[2] http://securitykitten.github.io/vm-checking-and-detecting/

- 303
- 1
- 6
this C++ code will detect Vmware Products such as express,esx,fusion or workstation
// VMWareDetector.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include <conio.h>
void CheckVM(void);
int main()
{
CheckVM();
_getch();
return 0;
}
void CheckVM(void)
{
unsigned int a, b;
__try {
__asm {
// save register values on the stack
push eax
push ebx
push ecx
push edx
// perform fingerprint
mov eax, 'VMXh' // VMware magic value (0x564D5868)
mov ecx, 0Ah // special version cmd (0x0a)
mov dx, 'VX' // special VMware I/O port (0x5658)
in eax, dx // special I/O cmd
mov a, ebx // data
mov b, ecx // data (eax gets also modified
// but will not be evaluated)
// restore register values from the stack
pop edx
pop ecx
pop ebx
pop eax
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
printf("\n[+] Debug : [ a=%x ; b=%d ]\n\n", a, b);
if (a == 'VMXh') { // is the value equal to the VMware magic value?
printf("Result : VMware detected\nVersion : ");
if (b == 1)
printf("Express\n\n");
else if (b == 2)
printf("ESX\n\n");
else if (b == 3)
printf("GSX\n\n");
else if (b == 4)
printf("Workstation\n\n");
else
printf("unknown version\n\n");
}
else
printf("Result : Not Detected\n\n");
}

- 507
- 4
- 14
-
you can also use `pushad` and `popad` instead of pushing and popping all registers manually – Toma Jun 26 '21 at 19:22
The easiest way I found to figure out whether my C# app is running on a vmware VM or not is to check the MAC address of the NIC card(s). If it's a VMware VM it would always be: 00:50:56:XX:YY:ZZ
You may enumerate through the NICs as resolved here.
-
11-1: of course VMware is free to change their MAC address format whenever they like, without telling you in advance – John Saunders Feb 18 '12 at 12:44
-
1According to http://standards.ieee.org VMWare uses: 00:05:69, 00:0C:29, 00:1C:14 as well as 00:50:56 for the Organization portion of the MAC Address. And as @John_Saunders said, they may add a new number to the list whenever they wish. – Jesse Chisholm May 26 '13 at 14:09
I have tested for 3 types - VirtualBox,Wmware and Huper-V
foreach (var mo in "Select * from Win32_ComputerSystem")
{
var model = (string)mo["Model"];
if (model == "VirtualBox" ||
model == "Virtual Machine" ||
model.StartsWith("VMware"))
{
return true;
}
}
return false;

- 900
- 1
- 12
- 26
I wanted to make this configurable so I converted @RobSiklos answer to a WMI query. Now I can put the query in a config location and change it when needed.
private static bool IsVirtual()
{
using (var searcher = new System
.Management
.ManagementObjectSearcher(@"SELECT * from Win32_ComputerSystem
WHERE (Manufacturer LIKE '%microsoft corporation%' AND Model LIKE '%virtual%')
OR Manufacturer LIKE '%vmware%'
OR Model LIKE '%VirtualBox%'"))
{
using (System.Management.ManagementObjectCollection items = searcher.Get())
{
if (items.Count > 0)
{
return true;
}
}
}
return false;
}
WQL Reference:
https://learn.microsoft.com/en-us/windows/win32/wmisdk/wql-sql-for-wmi

- 3,328
- 1
- 19
- 34
From Super User, this is the answer: look at the graphics driver. This is the code:
Dim driver As New ManagementObjectSearcher("Select * from Win32_PnPSignedDriver")
Dim driver_info As ManagementObject
Dim name As String
For Each driver_info In driver.Get()
caption = driver_info("DeviceName").ToString()
If caption.Contains("Standard") and caption.Contains("VGA") Then
' it's virtual machine
' do anything you need
End If
Next

- 13
- 1
- 7