Page 1 of 1
How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 03:51
by spinjector
I tried searching for this, but the keywords are too common and I received an avalanche of useless search results.
How can Windows tell it's running in a Vbox guest window..? I need to create some batch files that run differently depending if the disk image is on real hardware or a vm. In this particular case, I found my own easy way: it's for Windows PE and the %systemdrive% environment variable is always the x: drive. But what if it's a normal version of Windows running on the C: drive..? Then how could it be done..?
Thanks.
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 10:09
by socratis
Set your own environment variable? Write a file? Create a directory? All of the above?
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 14:26
by scottgus1
In a default installation in an unmodified Virtualbox guest, some of the pieces of hardware the Windows OS sees may have "Virtualbox" in the name.
Run "msinfo32" or look at the Device Manager. Also consider what you see if Guest Additions aren't installed.
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 16:23
by mpack
The OP wants something which is scriptable, which AFAIK none of those methods are. He'd have to write a small app to do some tests and return an result code to the script.
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 17:06
by scottgus1
Right, I think WMI will do it, which can run in a VBscript.
In a fresh install of Windows 7 in a guest, no Guest Additions, the "root\CIMV2" namespace, "Win32_DiskDrive" class finds a disk with a "caption" and "model" of "VBOX HARDDISK ATA Device" and a "PNPDeviceID" with "VBOX HARDDISK" in the text.
This VBscript returns these values along with a bunch of other stuff that could be removed (courtesy of
Microsoft Sysinternals WMI Scriptomatic):
Code: Select all
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
strComputer = "."
WScript.Echo
WScript.Echo "=========================================="
WScript.Echo "Computer: " & strComputer
WScript.Echo "=========================================="
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
WScript.Echo "Availability: " & objItem.Availability
WScript.Echo "BytesPerSector: " & objItem.BytesPerSector
strCapabilities = Join(objItem.Capabilities, ",")
WScript.Echo "Capabilities: " & strCapabilities
strCapabilityDescriptions = Join(objItem.CapabilityDescriptions, ",")
WScript.Echo "CapabilityDescriptions: " & strCapabilityDescriptions
WScript.Echo "Caption: " & objItem.Caption
WScript.Echo "CompressionMethod: " & objItem.CompressionMethod
WScript.Echo "ConfigManagerErrorCode: " & objItem.ConfigManagerErrorCode
WScript.Echo "ConfigManagerUserConfig: " & objItem.ConfigManagerUserConfig
WScript.Echo "CreationClassName: " & objItem.CreationClassName
WScript.Echo "DefaultBlockSize: " & objItem.DefaultBlockSize
WScript.Echo "Description: " & objItem.Description
WScript.Echo "DeviceID: " & objItem.DeviceID
WScript.Echo "ErrorCleared: " & objItem.ErrorCleared
WScript.Echo "ErrorDescription: " & objItem.ErrorDescription
WScript.Echo "ErrorMethodology: " & objItem.ErrorMethodology
WScript.Echo "FirmwareRevision: " & objItem.FirmwareRevision
WScript.Echo "Index: " & objItem.Index
WScript.Echo "InstallDate: " & WMIDateStringToDate(objItem.InstallDate)
WScript.Echo "InterfaceType: " & objItem.InterfaceType
WScript.Echo "LastErrorCode: " & objItem.LastErrorCode
WScript.Echo "Manufacturer: " & objItem.Manufacturer
WScript.Echo "MaxBlockSize: " & objItem.MaxBlockSize
WScript.Echo "MaxMediaSize: " & objItem.MaxMediaSize
WScript.Echo "MediaLoaded: " & objItem.MediaLoaded
WScript.Echo "MediaType: " & objItem.MediaType
WScript.Echo "MinBlockSize: " & objItem.MinBlockSize
WScript.Echo "Model: " & objItem.Model
WScript.Echo "Name: " & objItem.Name
WScript.Echo "NeedsCleaning: " & objItem.NeedsCleaning
WScript.Echo "NumberOfMediaSupported: " & objItem.NumberOfMediaSupported
WScript.Echo "Partitions: " & objItem.Partitions
WScript.Echo "PNPDeviceID: " & objItem.PNPDeviceID
strPowerManagementCapabilities = Join(objItem.PowerManagementCapabilities, ",")
WScript.Echo "PowerManagementCapabilities: " & strPowerManagementCapabilities
WScript.Echo "PowerManagementSupported: " & objItem.PowerManagementSupported
WScript.Echo "SCSIBus: " & objItem.SCSIBus
WScript.Echo "SCSILogicalUnit: " & objItem.SCSILogicalUnit
WScript.Echo "SCSIPort: " & objItem.SCSIPort
WScript.Echo "SCSITargetId: " & objItem.SCSITargetId
WScript.Echo "SectorsPerTrack: " & objItem.SectorsPerTrack
WScript.Echo "SerialNumber: " & objItem.SerialNumber
WScript.Echo "Signature: " & objItem.Signature
WScript.Echo "Size: " & objItem.Size
WScript.Echo "Status: " & objItem.Status
WScript.Echo "StatusInfo: " & objItem.StatusInfo
WScript.Echo "SystemCreationClassName: " & objItem.SystemCreationClassName
WScript.Echo "SystemName: " & objItem.SystemName
WScript.Echo "TotalCylinders: " & objItem.TotalCylinders
WScript.Echo "TotalHeads: " & objItem.TotalHeads
WScript.Echo "TotalSectors: " & objItem.TotalSectors
WScript.Echo "TotalTracks: " & objItem.TotalTracks
WScript.Echo "TracksPerCylinder: " & objItem.TracksPerCylinder
WScript.Echo
Next
Function WMIDateStringToDate(dtmDate)
WScript.Echo dtm:
WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _
Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
End Function
Note, to run the Scriptomatic correctly, make a shortcut to the downloaded hta file, then edit the "Target" to add "mshta.exe{space}" before the path to the hta file. Click OK to accept the new path, which should be "mshta.exe driveletter:\path\to\ScriptomaticV2.2.hta" Right-click the shortcut and choose Run As Administrator.
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 17:13
by socratis
Wait a minute, installing Windows unattended, potentially installing GAs and/or other goodies is scriptable, and creating "C:\Users\I_am_a_VM" on the guest is not? Or checking for its existence?
Re: How can Windows tell it's running on a VM..?
Posted: 29. Nov 2016, 17:21
by scottgus1
Looking for a special file would work, but if someone forgets to place the file, in the midst of all the other things one has to do to bring a new install into the mix, then the script would fail. My thought is that scripting a hunt for Virtualbox-specific hardware names or some other such would allow his special script to run successfully without needing to look for a manually-placed file, which someone may one day forget to make. As long as the developers don't change the hardware names the OP should be good.
Of course if there is a way to run a script on the host that automatically during or after the OS installation causes a special file to be made on the guest, then that would work too.