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 (not really a hardware issue pur sang) available harddisk space.
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 Microsoft's Scriptomatic tool and see what's available.
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, run Microsoft's Scriptomatic tool and/or search MSDN.
' List a selection of processor properties On Error Resume Next Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_Processor", "WQL", 48 ) 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 SP3, Vista and Server 2008, not in Windows XP SP2 and older versions.
If in doubt, you may want to count the For Each loop's iterations.
The table below gives a summary of some of the listed properties and some possible values.
This listing is by no means complete.
Full details can be found on MSDN.
| Win32_Processor Class | ||||
|---|---|---|---|---|
| Property | Values | Descriptions | Values | Descriptions |
| Architecture | 0 1 2 |
x86 MIPS Alpha |
3 6 9 |
PowerPC Intel Itanium x64 |
| Family | 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 24 25 26 27 |
Unknown 8086 80286 80386 80486 8087 80287 80387 80487 Pentium Pentium Pro Pentium II Pentium with MMX Celeron Pentium II Xeon Pentium III M1 M2 AMD Duron K5 K6 K6-2 |
28 29 30 31 128 130 131 132 160 176 177 178 179 181 182 183 184 185 190 300 301 302 |
K6-3 AMD Athlon AMD2900 K6-2+ Weitek Itanium AMD Athlon 64 AMD Opteron V30 Family Pentium III Xeon Pentium III with SpeedStep Pentium 4 Intel Xeon Intel Xeon MP AMD Athlon XP AMD Athlon MP Intel Itanium 2 Intel Pentium M K7 6x86 MediaGX MII |
| ProcessorType | 1 2 3 |
Other Unknown Central Processor |
4 5 6 |
Math Processor DSP Processor Video Processor |
| StatusInfo | 1 2 3 |
Other Unknown Enabled |
4 5 |
Disabled Not Applicable |
To check for a 1GHz Pentium 4 or better, we would have to list all processors of ProcessorType 3 (Central Processor), with StatusInfo 3 (Enabled), Architecture 0 (x86) and a CurrentClockSpeed value of 1000 (MHz) or more and then check for several "Family values".
And how about AMD processors?
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:
' 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'"
Set objWMIService = GetObject( "winmgmts://./root/CIMV2" )
Set colItems = objWMIService.ExecQuery( strQuery, "WQL", 48 )
' 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?
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
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.
intMem = 0 intRC = 0 Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_PhysicalMemory", "WQL", 48 ) ' 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 batch code will return this value:
SET Key=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management REG Query "%Key%" /v PhysicalAddressExtension
The output will look like this:
! REG.EXE VERSION 3.0 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management PhysicalAddressExtension REG_DWORD 0x1
With a bit more code we can store the result in a variable:
SET PAE=0
SET Key=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
FOR /F "skip=4 tokens=3" %%A IN ('REG Query "%Key%" /v PhysicalAddressExtension') DO (
IF %%A0 EQU 16 (
SET PAE=1
)
)
Now the environment variable PAE will be set to 1 if PAE is enabled, or 0 if not.
If you prefer VBScript, try the following code:
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
All right... and here's the KiXtart code as well:
$Hive = "HKEY_LOCAL_MACHINE" $Key = "\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" $Value = "PhysicalAddressExtension" "Physical Address Extension enabled: " + ReadValue( $Hive + $Key, $Value )
Whereas querying free disk space may seem quite simple, the following code may look intimidating.
Most of it, however, is handling command line arguments and error checking.
The script accepts up to 2 command line arguments: a drive letter and/or the required free disk space in MBs.
' Default values strQuery = "SELECT * FROM Win32_LogicalDisk WHERE DriveType='3'" intReq = 0 intRC = 1 strDrv = "" ' In case of a single command line argument, determine if it ' is a drive letter or a number (required free space in MBs) ' and modify the WMI query if necessary If WScript.Arguments.Unnamed.Count = 1 Then strArg1 = UCase( WScript.Arguments.Unnamed(0) ) If IsNumeric( WScript.Arguments.Unnamed(0) ) Then ' Number (required free disk space in MBs) was specified intReq = CLng( strArg1 ) Else strDrv = UCase( strArg1 ) If IsDrive( strDrv ) Then ' A drive was specified, modify the WMI query accordingly strQuery = strQuery & " AND DeviceID='" & strDrv & "'" Else ' Invalid command line argument WScript.Quit 2 End If End If End If ' In case both a drive and a required amount of free space are specified, ' we need to determine in what order they were specified; we also need to ' modify the WMI query If WScript.Arguments.Unnamed.Count = 2 Then ' Determine the order of the arguments If IsNumeric( WScript.Arguments.Unnamed(0) ) Then intReq = CLng( WScript.Arguments.Unnamed(0) ) strDrv = UCase( WScript.Arguments.Unnamed(1) ) Else intReq = CLng( WScript.Arguments.Unnamed(1) ) strDrv = UCase( WScript.Arguments.Unnamed(0) ) End If ' Check if the arguments were both valid and modify the WMI query If IsDrive( strDrv ) Then strQuery = strQuery & " AND DeviceID='" & strDrv & "'" Else ' Invalid command line argument(s) WScript.Quit 2 End If End If Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( strQuery, "WQL", 48 ) For Each objItem In colItems intFree = CLng( objItem.FreeSpace / ( 1024 * 1024 ) ) intSize = CLng( objItem.Size / ( 1024 * 1024 * 1024 ) ) Select Case WScript.Arguments.Unnamed.Count Case 1 ' In case of a single command line argument, display either ' the free disk space for the specified drive, or the first ' drive with sufficient free disk space If intFree >= intReq Then intRC = 0 If strDrv = "" Then strDrv = objItem.DeviceID WScript.Echo strDrv Else WScript.Echo intFree End If End If Case 2 ' In case of 2 command line arguments only the return code ' needs to be set, nothing will be displayed If intFree >= intReq Then intRC = 0 End If Case Else ' List some properties for all local harddisk partitions strMsg = "Device ID : " & objItem.DeviceID & vbCrLf _ & "Volume Name : " & objItem.VolumeName & vbCrLf _ & "Size : " & intSize & " GB" & vbCrLf _ & "Free Space : " & intFree & " MB" & vbCrLf _ & "File System : " & objItem.FileSystem & vbCrLf WScript.Echo strMsg intRC = 0 End Select Next ' Exit with the appropriate return code WScript.Quit intRC Function IsDrive( myDrv ) blnDrv = True On Error Resume Next If Len( myDrv ) <> 2 Then blnDrv = False If InStr( myDrv, ":" ) <> 2 Then blnDrv = False If Left( myDrv, 1 ) < "C" Then blnDrv = False If Left( myDrv, 1 ) > "Z" Then blnDrv = False On Error Goto 0 IsDrive = blnDrv End Function
The table below gives a summary of some of the listed properties and some possible values.
This listing is by no means complete.
Full details can be found on MSDN.
| Win32_LogicalDisk Class | ||||
|---|---|---|---|---|
| Property | Values | Descriptions | Values | Descriptions |
| DriveType | 0 1 2 3 |
Unknown No Root Directory Removable Disk Local Disk |
4 5 6 |
Network Drive Compact Disc RAM Disk |
| MediaType | 0 1 2 3 4 5 6 7 8 9 10 11 |
Unknown 5.25" FDD (1.2 MB - 512 bytes/sector) 3.5" FDD (1.44 MB - 512 bytes/sector) 3.5" FDD (2.88 MB - 512 bytes/sector) 3.5" FDD (20.8 MB - 512 bytes/sector) 3.5" FDD (720 KB - 512 bytes/sector) 5.25" FDD (360 KB - 512 bytes/sector) 5.25" FDD (320 KB - 512 bytes/sector) 5.25" FDD (320 KB - 1024 bytes/sector) 5.25" FDD (180 KB - 512 bytes/sector) 5.25" FDD (160 KB - 512 bytes/sector) Removable media other than floppy |
12 13 14 15 16 17 18 19 20 21 22 |
Fixed hard disk media 3.5" FDD (120 MB - 512 bytes/sector) 3.5" FDD (640 KB - 512 bytes/sector) 5.25" FDD (640 KB - 512 bytes/sector) 5.25" FDD (720 KB - 512 bytes/sector) 3.5" FDD (1.2 MB - 512 bytes/sector) 3.5" FDD (1.23 MB - 1024 bytes/sector) 5.25" FDD (1.23 MB - 1024 bytes/sector) 3.5" FDD (128 MB - 512 bytes/sector) 3.5" FDD (230 MB - 512 bytes/sector) 8" FDD (256 KB - 128 bytes/sector) |
| StatusInfo | 1 2 3 |
Other Unknown Enabled |
4 5 |
Disabled Not Applicable |
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:
Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_DisplayConfiguration", "WQL", 48 ) For Each objItem In colItems WScript.Echo objItem.PelsWidth & " x " & objItem.PelsHeight & ", " & objItem.BitsPerPel & " bits/pixel" 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, the third (optional) argument is the minimum required number of bits per pixel:
intRC = 0 intBpp = 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 Syntx End If If .Count = 3 Then If IsNumeric( .Item(2) ) Then intBpp = CInt( .Item(2) ) Else Syntax End If End If Else Syntax End If End With ' Read the actual screen resolution strQuery = "SELECT * FROM Win32_DisplayConfiguration" Set objWMIService = GetObject( "winmgmts://./root/CIMV2" ) Set colItems = objWMIService.ExecQuery( strQuery, "WQL", 48 ) ' Compare the actual resolution with the minimum required values For Each objItem In colItems If objItem.PelsWidth < intHor Then intRC = 1 If objItem.PelsHeight < intVert Then intRC = 1 If objItem.BitsPerPel < intBpp 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 [ min_bpp ]" & 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 _ & " ""min_bpp"" is the minimum required number of bits per pixel" .Quit 2 End With End Sub
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 | ||
| 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 |
||
| 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 | ||
| VideoROM.bat VideoROM.kix VideoROM.pl VideoROM.rex VideoROM.vbs |
Display video adapter summary | DEBUG WMI DEBUG DEBUG WMI |
| page last uploaded: 18 November 2011, 11:39 |