Before installing software we often need to know if a computer meets that software's minimum hardware requirements, like the type of processor, the amount of physical memory, the screen resolution or available harddisk space (rarely a hardware issue).
There are many alternative ways to determine installed software versions, but to check hardware nothing beats WMI.
On this page, I will show several sample WMI queries to check hardware requirements.
Some ready-to-run sample scripts are available as well, including some that don't use WMI.
To find out which WMI class you need, you can search MSDN's list of WMI Classes, or you can run one of many available tools to browse WMI:
Instead of using WMI, you can also retrieve system information from DMI, also known as SMBIOS.
Though the information available through SMBIOS is not as extensive as the information available through WMI, it is often much faster to retrieve.
There are no native commands to read SMBIOS information, however, so you will need a third party tool like DMIDecode.exe, or you can write and compile your own program.
Use the command dmidecode
to list all available information.
Use the command dmidecode -t
to see what categories of information are available, then select a category and use dmidecode -t category
to list available information for that category.
For programmers, the WINAPI (user32.dll) GetSystemMetrics
function may be a useful tool to retrieve information, especially on monitors and input devices.
I wrote a "wrapper" for this function, GetSystemMetrics.exe, which can be used in batch files to retrieve system information.
The .NET SystemInformation
class is a great help to detect all kinds of Windows GUI settings.
I wrote two "wrappers" for this class too, SystemInformation.exe for batch files, and SystemInformation.dll for COM enabled languages (e.g. KiXtart and VBScript).
Microsoft's DEVCON (DEVice manager CONsole tool) can be used in batch files to detect, remove or install devices and drivers.
Some sample scripts use DEBUG, native since MS-DOS, but not in 64-bit Windows versions.
On this page, I will provide some alternatives to WMI, all requiring DMIDecode.exe or GetSystemMetrics.exe.
The following code lists some of the CPU properties that we may want to query before starting a software installation.
For the full list of available properties, use one of the WMI tools listed above and/or search MSDN.
Batch
KiXtart
PowerShell
VBScript
' List a selection of processor properties On Error Resume Next Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_Processor" ) For Each objItem In colItems WScript.Echo "Architecture : " & objItem.Architecture WScript.Echo "Current Clock Speed : " & objItem.CurrentClockSpeed & " MHz" WScript.Echo "Description : " & objItem.Description WScript.Echo "Device ID : " & objItem.DeviceID WScript.Echo "External Clock Speed : " & objItem.ExtClock & " MHz" WScript.Echo "Family : " & objItem.Family WScript.Echo "Level : " & objItem.Level WScript.Echo "Manufacturer : " & objItem.Manufacturer WScript.Echo "Name : " & objItem.Name WScript.Echo "Number Of Cores : " & objItem.NumberOfCores WScript.Echo "Number Of Logical Processors : " & objItem.NumberOfLogicalProcessors WScript.Echo "Other Family Description : " & objItem.OtherFamilyDescription WScript.Echo "Processor Type : " & objItem.ProcessorType WScript.Echo "Revision : " & objItem.Revision WScript.Echo "Status Info : " & objItem.StatusInfo WScript.Echo "Stepping : " & objItem.Stepping WScript.Echo "Version : " & objItem.Version WScript.Echo Next
The NumberOfCores
and NumberOfLogicalProcessors
properties are available in Windows XP Professional SP3 and later, not in Windows XP SP2 and older versions.
If in doubt, you may want to count the For Each
loop's iterations.
Full details on the Win32_Processor class' properties and their possible values and meaning can be found on MSDN.
To check for a 1GHz Intel Pentium 4 or better, we would have to list all processors of ProcessorType
3 (Central Processor), with StatusInfo
3 (Enabled), Architecture
0 (x86) or 9 (x64), and a CurrentClockSpeed
value of 1000 (MHz) or more and then check for several "Family values".
AMD processors will have to be tested separately...
The following sample code exits with return code 0 if all of the requirements mentioned are met for at least one processor, or 1 if not:
Batch
KiXtart
PowerShell
VBScript
' Set return code to 1 (requirements not met) intRC = 1 ' Filter for the proper Architecture, ProcessorType and StatusInfo strQuery = "SELECT * FROM Win32_Processor WHERE ProcessorType='3' AND StatusInfo='3' AND ( Architecture='0' OR Architecture='9' )" Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( strQuery ) ' Check each processor For Each objItem In colItems ' Check the clock speed If objItem.CurrentClockSpeed > 999 Then ' Is the ProcessorFamily value in the 178..183 range? ' Remove the range check if Family requirement isn't that strict If objItem.Family > 177 And objItem.Family < 184 Then ' If all requirements are met, set the return code to 0 intRC = 0 End If End If Next ' Exit with the proper return code WScript.Quit intRC
The command dmidecode -t processor
will provide information like this:
# dmidecode 2.10 SMBIOS 2.5 present. Handle 0x0004, DMI type 4, 40 bytes Processor Information Socket Designation: AM3 Type: Central Processor Family: Other Manufacturer: AMD ID: A0 0F 10 00 FF FB 8B 17 Version: AMD Phenom(tm) II X6 1100T Processor Voltage: 1.5 V External Clock: 200 MHz Max Speed: 3700 MHz Current Speed: 3300 MHz Status: Populated, Enabled Upgrade: Other L1 Cache Handle: 0x0005 L2 Cache Handle: 0x0006 L3 Cache Handle: 0x0007 Serial Number: To Be Filled By O.E.M. Asset Tag: To Be Filled By O.E.M. Part Number: To Be Filled By O.E.M. Core Count: 6 Core Enabled: 6 Characteristics: 64-bit capable
Without command line arguments, the following code displays the physical memory in MBs.
If a number is specified, nothing is displayed; the script will exit with return code 0 if the actual memory matches or exceeds the specified number of MBs, or 1 if it is less.
Batch
KiXtart
PowerShell
VBScript
intMem = 0 intRC = 0 Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_PhysicalMemory" ) ' Sum the capacity of all memory modules For Each objItem In colItems intMem = intMem + objItem.Capacity Next ' If a minimum number of MB was specified, check if the actual ' amount of physical memory matches this minimum requirement; ' if no number is specified, just display the number of MBs If WScript.Arguments.Unnamed.Count = 1 Then ' Set return code to 1 (requirement not met) intRC = 1 intReq = WScript.Arguments.Unnamed(0) If IsNumeric( intReq ) Then ' If the requirement is met, set return code to 0 If intMem >= 1024 * 1024 * intReq Then intRC = 0 End If Else ' Display the physical memory in MBs WScript.Echo intMem / ( 1024 * 1024 ) End If ' Exit with the appropriate return code WScript.Quit intRC
If more than 3GB of physical memory is required (some programs, like AutoCAD, really do) and installed in Windows XP, check if PAE is enabled: if it is, the registry DWORD value PhysicalAddressExtension
in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
will be 0x1
.
The following code will return this value:
Batch
KiXtart
PowerShell
$regpath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\" ( Get-ItemProperty -Path $regpath -Name "PhysicalAddressExtension" ).PhysicalAddressExtension | Select-Object -OutVariable PAE $ENV:PAE = $PAE
VBScript
Set wshShell = CreateObject( "WScript.Shell" ) strHive = "HKEY_LOCAL_MACHINE" strKey = "\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\" strValue = "PhysicalAddressExtension" If CInt( wshShell.RegRead( strHive & strKey & strValue ) ) = 1 Then blnPAE = True Else blnPAE = False End If Set wshShell = Nothing WScript.Echo "Physical Address Extension enabled: " & blnPAE
The command dmidecode -t memory
will provide information like this:
# dmidecode 2.10 SMBIOS 2.5 present. Handle 0x003B, DMI type 16, 15 bytes Physical Memory Array Location: System Board Or Motherboard Use: System Memory Error Correction Type: None Maximum Capacity: 16 GB Error Information Handle: Not Provided Number Of Devices: 2 Handle 0x003D, DMI type 17, 27 bytes Memory Device Array Handle: 0x003B Error Information Handle: Not Provided Total Width: 64 bits Data Width: 64 bits Size: 8192 MB Form Factor: DIMM Set: None Locator: DIMM0 Bank Locator: BANK0 Type: DDR Type Detail: Synchronous Speed: 1333 MHz Manufacturer: Manufacturer00 Serial Number: SerNum00 Asset Tag: AssetTagNum0 Part Number: ModulePartNumber00 Handle 0x003F, DMI type 17, 27 bytes Memory Device Array Handle: 0x003B Error Information Handle: Not Provided Total Width: Unknown Data Width: Unknown Size: No Module Installed Form Factor: DIMM Set: None Locator: DIMM1 Bank Locator: BANK1 Type: Unknown Type Detail: None Speed: Unknown Manufacturer: Manufacturer01 Serial Number: SerNum01 Asset Tag: AssetTagNum1 Part Number: ModulePartNumber01
Querying free disk space may be quite simple, as the batch file demonstrates.
The other scripts below may look intimidating, but they are more usefull to test for hardware requirements.
They require a command line argument specifying the required free disk space in MBs or GBs, and list the drives that meet the requirement.
They return an "ErrorLevel" 0 if at least one drive meets the requirement, or 1 if not.
The VBScript version also accepts a drive letter as an optional second argument.
Batch
KiXtart
PowerShell
VBScript
Option Explicit Dim intFree, intMinReq, intRC, strDrive, strQuery, objWMIService, colItems, objItem If WScript.Arguments.Count = 1 Then intMinReq = CLng( WScript.Arguments(0) ) strQuery = "SELECT * FROM Win32_LogicalDisk WHERE DriveType='3'" ElseIf WScript.Arguments.Count = 2 Then strDrive = WScript.Arguments(0) intMinReq = CLng( WScript.Arguments(1) ) strQuery = "SELECT * FROM Win32_LogicalDisk WHERE DriveType='3' AND DeviceID='" & strDrive & "'" Else WScript.Echo "Usage: " & WScript.ScriptName & " [ drive ] minfree" & vbCrLf & vbCrLf _ & "Where: drive is the drive to check for free space (default: all)" & vbCrLf _ & " minfree is the minimum amount of free space required, in MB" & vbCrLf & vbCrLf _ & "Returns: return code 0 if the specified drive (or if not specified: ANY drive)" & vbCrLf _ & " has the required amount of free space available, 1 if not, 2 on errors" WScript.Quit 2 End If Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( strQuery ) intRC = 1 For Each objItem In colItems intFree = CLng( objItem.FreeSpace / ( 1024 * 1024 ) ) If intFree >= intMinReq Then WScript.Echo objItem.DeviceID & vbTab & intFree & " MB" intRC = 0 End If Next WScript.Quit intRC
Full details on the Win32_LogicalDisk class' properties and their possible values and meaning can be found on MSDN.
Screen resolutions are hardly ever a problem these days.
However, you still may want to check it for some installations.
WMI makes this a snap:
Batch
KiXtart
PowerShell
VBScript
Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_VideoController" ) For Each objItem In colItems WScript.Echo objItem.CurrentHorizontalResolution & " x " & objItem.CurrentVerticalResolution & ", " & objItem.CurrentNumberOfColors & " colors" Next
The code above is fine to "manually" check the resolution, but for unattended installations a comparison is more useful.
The following code will display nothing unless invalid arguments are passed on the command line.
It will exit with a return code 0 if the actual screen resolution meets the specified minimum requirements, or 1 if it doesn't.
Mandatory command line arguments are the minimum required horizontal and vertical resolution in pixels:
Batch
KiXtart
PowerShell
VBScript
intRC = 0 intColors = 0 intHor = 0 intVert = 0 ' Parse the command line arguments With WScript.Arguments.Unnamed If .Count = 2 Or .Count = 3 Then If IsNumeric( .Item(0) ) Then intHor = CInt( .Item(0) ) Else Syntax End If If IsNumeric( .Item(1) ) Then intVert = CInt( .Item(1) ) Else Syntax End If If .Count = 3 Then If IsNumeric( .Item(2) ) Then intColors = CInt( .Item(2) ) Else Syntax End If End If Else Syntax End If End With ' Read the actual screen resolution strQuery = "SELECT * FROM Win32_VideoController" Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( strQuery ) ' Compare the actual resolution with the minimum required values For Each objItem In colItems If objItem.CurrentHorizontalResolution < intHor Then intRC = 1 If objItem.CurrentVerticalResolution < intVert Then intRC = 1 Next Set colItems = Nothing Set objWMIService = Nothing ' Exit with the appropriate return code WScript.Quit intRC Sub Syntax With WScript .Echo "Check if the screen resolution meets your minimum requirements" & vbCrLf & vbCrLf _ & "Usage: " & UCase( .ScriptName ) & " min_hor min_vert" & vbCrLf & vbCrLf _ & "Where: ""min_hor"" is the minimum required horizontal resolution in pixels" & vbCrLf _ & " ""min_vert"" is the minimum required vertical resolution in pixels" & vbCrLf & vbCrLf _ & "Note: Return code 0 if requirements are met, 1 if not, 2 on errors" .Quit 2 End With End Sub
GetSystemMetrics.exe 0
or GetSystemMetrics.exe SM_CXSCREEN
return the horizontal resolution of the primary displayGetSystemMetrics.exe 1
or GetSystemMetrics.exe SM_CYSCREEN
return the vertical resolution of the primary displaySystemInformation.exe PrimaryMonitorSize
returns the horizontal and vertical resoltion of the primary displayGetSystemMetrics.exe 80
or GetSystemMetrics.exe SM_CMONITORS
or SystemInformation.exe MonitorCount
return the number of connected monitorsSystemInformation.exe MonitorsSameDisplayFormat
to find out if all connected monitors have identical resolutionsREG.EXE Query HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY /f MaxResolution /s
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\SAM0467\7&cf6ea47&0&UID4194576\Device Parameters
MaxResolution REG_SZ 1600,1200 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\SAM0467\7&cf6ea47&0&UID4194578\Device Parameters MaxResolution REG_SZ 1600,1200 End of search: 2 match(es) found.
Use the commands GetSystemMetrics.exe /L
and SystemInformation.exe (without command line argument) to list all available properties.
There is a lot of overlap in GetSystemMetrics.exe and SystemInformation.exe, decide for yourself which one works best for a particular task.
To determine if the local computer is a laptop you can check the ChassisTypes
property in WMI's Win32_SystemEnclosure
class, and/or check if WMI's Win32_Battery
class has any instances (desktops usually don't have any).
Batch
KiXtart
PowerShell
VBScript
strComputer = "." intIsLaptop = 0 Set objWMIService = GetObject( "winmgmts://" & strComputer & "/root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_SystemEnclosure" ) For Each objItem in colItems For Each objSubItem In objItem.ChassisTypes Select Case objSubItem Case 8: ' Portable Case 9: ' Laptop Case 10: ' Notebook Case 11: ' Hand Held Case 12: ' Docking Station Case 14: ' Sub Notebook intIsLaptop = 1 End Select Next Next Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_Battery" ) If colItems.Count > 0 Then intIsLaptop = intIsLaptop + 1 Select Case intIsLaptop Case 0: WScript.Echo "This computer is definitely NOT a laptop" Case 1: WScript.Echo "This computer probably is a laptop" Case 2: WScript.Echo "This computer definitely is a laptop" Case Else: WScript.Echo "An error occurred" End Select Set colItems = Nothing Set objWMIService = Nothing
.NET's System.Windows.Forms.PowerStatus
class can be used to check for battery status.
Only PowerShell has a way of directly accessing this resource, for other scripting languages I wrote a wrapper in C#: SystemInformation.exe.
Check its help text for details on its usage.
Batch
PowerShell
💾 Click the floppy disk icons to download the ZIPped sources
💾 | Name | Description | Technique | Remarks |
---|---|---|---|---|
💾 | BootDisk.bat | Determine the boot disk, partition and drive letter | WMI | |
💾 | BootDriv.bat (DOS) BootDriv.bat (NT) BootDriv.bat (XP) BootDriv.rex BootDriv.vbs |
Return boot drive letter | Environment Environment WMI API WMI |
VBScript and XP versions created using script code found in TechNet Script Center: "Disks and File Systems" section (no longer available?) |
💾 | CDROM.bat CDROMXP.bat CDROM.kix CDROM.rex CDROM.vbs |
Display all CD-ROM drive letters | Registry FileSystem WMI FileSystem WMI |
|
💾 | CheckRes.vbs | Check if the screen resolution meets a specified minimum requirement, and exit with return code 1 if not | WMI | |
💾 | COMPorts.vbs | Display serial ports information | WMI | |
💾 | CPUSpeed.vbs | Display CPU speed for each processor | WMI | |
💾 | CPUSpeedTD.vbs | Display CPU speed for each processor in tab delimited format | WMI | |
💾 | CPUType.vbs | Display CPU type | WMI | |
💾 | CPUTypeTD.vbs | Display CPU type in tab delimited format | WMI | |
💾 | DiskSpc.bat | Display harddisk summary for any WMI enabled computer or for a list of computers | WMI | |
💾 | DispEDID.vbs | Display the monitor's EDID asset information | Registry | Based on a script by Michael Baird (link no longer available) |
💾 | Drives.bat | List local drive letters and types | Registry | |
💾 | FreeSpace.rex FreeSpace.vbs |
Display a disk space summary | API WMI |
|
💾 | GetCDROMDrives.bat GetCDROMDrivesXP.bat GetFlashDrives.bat GetFlashDrivesXP.bat |
List all CDROM or removable "flash" drive letters | Registry | |
💾 | GetPorts.bat GetPorts.pl GetPorts.rex |
Show I/O addresses for serial and parallel ports | DEBUG | DEBUG samples won't work in 64-bit Windows |
💾 | GetRAM.bat (NT4) GetRAM2K.bat (W2K) GetRAM.vbs |
Display the amount of physical memory installed | WINMSD WINMSD WMI |
VBScript version based on WMI Scripting Primer: Part 1 by Greg Stemp, Dean Tsaltas and Bob Wells. |
💾 | GetRes.bat GetResXP.bat GetRes.pl GetRes.ps1 GetRes.vbs |
Display Windows 2000's screen resolution and refresh rate | Registry Registry WMI WMI WMI |
|
💾 | GetSystemMetrics 0 GetSystemMetrics 1 GetSystemMetrics 80 |
Display width (0) or height (1) of primary display, or number of connected monitors (80) | GetSystemMetrics | Requires my GetSystemMetrics.exe wrapper. |
💾 | HardDisk.bat | List harddisks, their interfaces and revision numbers for any computer on the network | DEVCON | Requires Microsoft's DEVCON. The script will prompt you to download DEVCON if it isn't found. |
💾 | Hardware.bat Hardware.kix Hardware.vbs |
Display a basic hardware summary for any WMI enabled computer on the network | WMI | |
💾 | IsLaptop.kix IsLaptop.vbs |
Check if the script runs on a laptop or not | WMI | Based on Guy Thomas' CHASSIS.VBS script |
💾 | Memory.bat | Show the amount of RAM in MB | 3rd Party | Use GetRAM.bat instead if you do not have the NT Resource Kit available |
💾 | Memory.ps1 | Display a physical memory summary | WMI | |
💾 | Modems | List all modems installed on the computer | DEVCON | Requires Microsoft's command line device management utility DEVCON |
💾 | NICSpeed.bat NICSpeed.kix NICSpeed.vbs |
Display ethernet adapters' link speed | WMI | |
💾 | PhysMem.vbs | Display a physical memory summary | WMI | |
💾 | SCSI.bat SCSI.kix SCSI.rex |
Enumerate disk drives (IDE and SCSI) | Registry | |
💾 | ShowPRN.ps1 ShowPRN.vbs |
Display all installed printers and their properties | WMI | |
💾 | ShowPRNT.vbs | Display all installed printers and their properties in TAB delimited format | WMI | |
💾 | TouchDetect.exe | Check if touch enabled input devices are available | GetSystemMetrics | Requires my GetSystemMetrics.exe wrapper. |
💾 | VideoROM.bat VideoROM.kix VideoROM.pl VideoROM.rex VideoROM.vbs |
Display video adapter summary | DEBUG WMI DEBUG DEBUG WMI |
DEBUG samples won't work in 64-bit Windows |
page last modified: 2024-02-26; loaded in 0.0030 seconds