How to Check if a Hypervisor is Present (Virtual Machine) in a Batch Script
In many scripting scenarios, particularly for system inventory or hardware-dependent tasks, you need to know if your script is running on a physical machine or inside a virtual machine (VM). A script might need to skip certain hardware checks (like getting a physical disk serial number) if it's in a VM, or it might apply different configurations for virtualized environments.
This guide will teach you the most reliable, built-in methods for detecting a hypervisor. You will learn how to use the WMIC command to check the computer's model and the systeminfo command to look for direct evidence of virtualization, allowing your batch script to be "VM-aware."
The Core Concept: Identifying Virtualized Hardware
There is no single environment variable like %IS_VM%. Instead, a script must look for clues left behind by the virtualization software (the hypervisor). Hypervisors like VMware, Hyper-V, and VirtualBox typically report a "virtual" model name for the computer system or BIOS, which is a very reliable indicator.
Method 1 (Recommended for Scripting): Using WMIC
The WMIC (Windows Management Instrumentation Command-line) utility is the best tool for this because it provides clean, specific, and easily parsable data about the system's hardware. We can check the computer's model, which is almost always a dead giveaway.
Command: WMIC COMPUTERSYSTEM GET Model
Expected Output
- On a Physical Machine: The output will be the actual hardware model (e.g.,
Latitude 5420,HP EliteDesk 800 G5). - On a VMware VM:
VMware Virtual Platform - On a Hyper-V VM:
Virtual Machine - On a VirtualBox VM:
VirtualBox
By checking for these keywords, we can reliably determine if the script is in a VM.
Method 2 (Simple Alternative): Using systeminfo
The systeminfo command provides a wealth of system details. On systems where Hyper-V is the hypervisor (or is enabled), it will explicitly state that a hypervisor has been detected.
Command: systeminfo | find "Hyper-V"
If Hyper-V is present, you will see a line like this in the output:
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.
While simple, this method is less universal than the WMIC approach (it's best for detecting Hyper-V specifically) and is much slower to run.
Example Script: A Comprehensive VM Detection Script
This script uses the recommended WMIC method to check the system model and sets a flag variable if it detects a virtual machine.
@ECHO OFF
SETLOCAL
SET "IsVM=0"
SET "VM_Type=Physical"
ECHO --- Checking for Virtual Machine Environment ---
ECHO.
REM --- Use WMIC to get the computer model ---
FOR /F "tokens=*" %%M IN ('WMIC COMPUTERSYSTEM GET Model') DO (
SET "SystemModel=%%M"
REM Check the model string for common virtualization keywords
ECHO !SystemModel! | findstr /I /C:"Virtual" > NUL
IF !ERRORLEVEL! EQU 0 SET "IsVM=1" & SET "VM_Type=Virtual Machine (Generic)"
ECHO !SystemModel! | findstr /I /C:"VMware" > NUL
IF !ERRORLEVEL! EQU 0 SET "IsVM=1" & SET "VM_Type=VMware"
ECHO !SystemModel! | findstr /I /C:"Hyper-V" > NUL
IF !ERRORLEVEL! EQU 0 SET "IsVM=1" & SET "VM_Type=Hyper-V"
)
ECHO --- Result ---
ECHO System Model: %SystemModel%
IF %IsVM% EQU 1 (
ECHO [CONCLUSION] A hypervisor was detected.
ECHO VM Type detected as: %VM_Type%
) ELSE (
ECHO [CONCLUSION] This appears to be a physical machine.
)
ENDLOCAL
This script requires DelayedExpansion (!Var!) if you want to use the SystemModel variable inside the same FOR loop where it is set.
How the script works:
WMIC COMPUTERSYSTEM GET Model: This command is executed, and its output (a header and the model name) is captured by theFOR /Floop.SET "SystemModel=%%M": The line containing the model name is assigned to theSystemModelvariable.ECHO !SystemModel! | findstr /I /C:"...": This is the core check. WeECHOthe model string and pipe it tofindstr./I: Makes the search case-Insensitive./C:"Virtual": Searches for the Constant literal string "Virtual".
IF !ERRORLEVEL! EQU 0 ...: Iffindstrfinds a match, itsERRORLEVELis0, and we set ourIsVMflag to1(true).- We repeat this check for other common hypervisor names like "VMware" for more specific detection.
Common Pitfalls and How to Solve Them
-
Administrator Rights: While
WMICqueries can often be run as a standard user, they are most reliable when run as an Administrator. An elevated prompt ensures full access to all WMI providers. -
Evasive VMs: In some high-security or specific testing environments, a virtual machine may be configured to hide its virtual nature by spoofing a physical machine's model number. The methods described here will detect over 99% of standard VMs but are not foolproof against intentional evasion.
-
Nested Virtualization: If you are running a VM inside another VM, the tools will typically only detect the first-level hypervisor.
Practical Example: A Hardware-Aware Inventory Script
This script gathers system information. It intelligently skips the step of getting the physical disk serial number if it detects that it's running in a VM, as virtual disks have generic or non-existent serial numbers.
@ECHO OFF
SETLOCAL
SET "IsVM=0"
FOR /F "tokens=*" %%M IN ('WMIC COMPUTERSYSTEM GET Model ^| findstr /I /C:"Virtual" /C:"VMware"') DO (
SET "IsVM=1"
)
ECHO --- System Inventory Script ---
ECHO Computer Name: %COMPUTERNAME%
WMIC OS GET Caption | find "Microsoft"
IF %IsVM% EQU 1 (
ECHO [INFO] Virtual machine detected. Skipping physical hardware checks.
) ELSE (
ECHO [INFO] Physical machine detected. Getting hardware serials...
ECHO.
ECHO --- BIOS Serial Number ---
WMIC BIOS GET SerialNumber
ECHO.
ECHO --- Physical Disk Serial Number ---
WMIC DISKDRIVE GET Model,SerialNumber
)
ECHO --- Report Complete ---
ENDLOCAL
Conclusion
While Windows provides no direct command to check for virtualization, you can reliably infer it by inspecting the hardware information exposed by the system.
- The
WMIC COMPUTERSYSTEM GET Modelcommand is the most reliable and recommended method for scripting. - Check the output of this command for keywords like "Virtual", "VMware", or "Hyper-V".
- The
systeminfocommand provides a simple alternative, especially for detecting Hyper-V.
By incorporating this check, you can create smarter, more adaptable scripts that behave correctly in both physical and virtual environments.