With WMIC we can use WMI queries in batch files.
Like WMI itself, WMIC is available as of Windows XP Professional.
And though WMI can be added on Window NT 4 and 2000, WMIC requires Windows XP Professional or later.
Though the C in WMIC seems to stand for Console, I prefer to interpret it as WMI for the Command line.
To start WMIC in interactive console mode, just type:
/? in the WMIC console will give you the same on-screen help you would get after typing:
at the command prompt: a list of switches and aliases.
Since we are dealing with batch files here, I'll use the commands for Command Line Mode from now on.
If you prefer the Interactive Console Mode, just remove "WMIC" from the start of each command line.
GETcommand to read properties of the specified WMI class.
WMIC OS Get /?
GETcommand, it won't change any setting.
SETcommand you can set (change) properties, unless they are read-only.
WMIC OS Set /?
SETcommand unless you are absolutely sure about the consequences.
CALLcommand you can call a WMI method for the specified class.
WMIC OS Call /?
CALLcommand unless you are absolutely sure about the consequences.
Now let's try the following commands:
WMIC BIOS WMIC BIOS Get Manufacturer WMIC BIOS Get Manufacturer,Name,Version /Format:csv WMIC BIOS Get Manufacturer,Name,Version /Format:list WMIC BIOS Get /Format:list WMIC BIOS Get Manufacturer,Name,Version /Format:htable
You may want to save the latter to a HTML file to view it in a browser:
WMIC /Output:bios.html BIOS Get Manufacturer,Name,Version /Format:htable START "" "%CD%.\bios.html"
Need the result pasted in another window?
Need to store the properties in variables? Try this (note the commas now being "escaped" by ˆ, carets):
FOR /F "tokens=*" %%A IN ('WMIC BIOS Get Manufacturerˆ,Nameˆ,Version /Value ˆ| FIND "="') DO ( SET BIOS.%%A ) SET BIOS
Try to figure out for yourself how that worked.
A hint: try the plain WMIC command, without the
FIND filtering and without the
FOR loops, and see what the output looks like...
Now prepend each of those lines with
Often WMI queries return far too much information, so we want to narrow down the selection.
For example, the following query against my own computer returns 27 instances, even though it has only one network adapter:
WMIC Path Win32_NetworkAdapter Get
|Note:||If all you want to know is the number of adapters, just list the indexes only:
WQL or WMI Query Language allows us to get only those instances matching the conditions set by a
The following modified query returns only 2 instances on my computer (it turns out the BlueTooth dongle is also considered a physical network adapter):
WMIC Path Win32_NetworkAdapter Where "PhysicalAdapter=TRUE" Get
This is pretty straightforward.
Now list only adapters manufactured by Realtek.
The following command will not work:
WMIC Path Win32_NetworkAdapter Where "Manufacturer=Realtek" Get
Realtek in this case is a string, so we need to place it in quotes, preferably without confusing them with the quotes for the entire
The following commands will work:
WMIC Path Win32_NetworkAdapter Where "Manufacturer='Realtek'" Get
WMIC Path Win32_NetworkAdapter Where (Manufacturer='Realtek') Get
WMIC Path Win32_NetworkAdapter Where (Manufacturer="Realtek") Get
WMIC Path Win32_NetworkAdapter Where "Manufacturer = 'Realtek'" Get
Parentheses are required for more complex
WMIC Path Win32_NetworkAdapter Where ( Manufacturer = "Realtek" And PhysicalAdapter = TRUE ) Get
However, these parenthesis tend to break your
FOR /F loops...
A limitation of the
WHERE clause is that it cannot select properties of type array.
Take a good look at WQL if you intend to use
Instead of the BIOS alias, we might just as well have used Path Win32_BIOS, it wouldn't have made any difference.
The reason I mention this is that my WMI Code Generator does indeed use Path followed by the full class name.
Besides, not every class has its own WMIC alias.
To find the full class name behind an alias, use the following command:
WMIC ALIAS alias_name Get Target [ /Format:list ]
The result will look like this:
Target=Select * from full_class_name
WMIC alias_name Get CreationClassName [ /Format:list ]
The result will be one or more lines like this:
To list all available aliases, try this short batch file:
@ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION FOR /F "skip=1 tokens=1,5" %%A IN ('WMIC /NameSpace:\\root\CLI Path MSFT_CliAlias Get FriendlyName^,Target ^| FIND "*"') DO SET Alias.%%A=%%B FOR /F "tokens=2,3 delims==." %%A IN ('SET Alias') DO ( SET "_Alias=%%A " SET _Alias=!_Alias:~0,20! ECHO !_Alias! = %%B ) ENDLOCAL
I have not yet found a way to make WMIC list all WMI classes available, but the following code comes close:
FOR /F %%A IN ('WMIC /? ˆ| FINDSTR /R /B /C:"[A-Z][A-Z][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ][A-Z ]" ˆ| FINDSTR /R /B /V /C:"For more information"') DO ( FOR /F "tokens=4" %%B IN ('WMIC ALIAS %%A Get Target /Value 2ˆ>NUL ˆ| FIND "="') DO ( ECHO.%%B ) )
The first line extracts a list of aliases from WMIC's help screen, and these aliases are "fed" to the second WMIC command line which retrieves the Target class, as discussed above.
Unfortunately, not all WMI classes have an alias, so some (most) will not be included in the list.
The resulting list is not sorted and may contain duplicates.
ListWMIClasses.bat extends the code above to display a sorted list without duplicates.
By far the easiest and most reliable way to find all WMI classes available is to use Microsoft's ScriptOMatic or my own WMI Code Generator, both with GUI, or ListWMIClasses.vbs.
/Node:remote_computer switch to query remote computers.
/NameSpace:\\root\other_namespace switch to query classes that are not located in the default CIMV2 namespace.
It is possible to use WMIC to read, write or delete registry keys and values, but I would not recommend it, it is not for the faint of heart.
REG.EXE is a lot easier to use.
The reason I still mention this feature of WMIC is the possibility to check if the current user has permissions to access a registry key or value:
SET KEY_QUERY_VALUE="&H1" SET KEY_SET_VALUE="&H2" SET KEY_CREATE_SUB_KEY="&H4" SET KEY_ENUMERATE_SUB_KEYS="&H8" SET KEY_NOTIFY="&H10" SET KEY_CREATE="&H20" SET DELETE="&H10000" SET READ_CONTROL="&H20000" SET WRITE_DAC="&H40000" SET WRITE_OWNER="&H80000" SET HKEY_CLASSES_ROOT="&H80000000" SET HKEY_CURRENT_USER="&H80000001" SET HKEY_LOCAL_MACHINE="&H80000002" SET HKEY_USERS="&H80000003" SET HKEY_CURRENT_CONFIG="&H80000005" WMIC /NameSpace:\\root\default Class StdRegProv Call CheckAccess hDefKey=%HKEY_LOCAL_MACHINE% sSubKeyName="Software\My Program" uRequired=%KEY_SET_VALUE%
This code will return "errorlevel" 0 ("true") if the current user has permission to set values in
HKEY_LOCAL_MACHINE\Software\My Program or 2 ("false") if not.
To combine permissions, add their associated hexadecimal numbers.
|Notes:||1||You don't have to use environment variables to store the hexadecimal values:
will work fine.
|2||The online documentation on MSDN for the
To find the correct parameter name I used
There are some WMIC samples available on this site:
Except for CheckRegAccess.bat, PausePrinting.bat, ResumePrinting.bat, Printing.bat, and the reboot and shutdown, these samples are all limited to Get (read) property values only.
More samples (be carefull, some of these do actually change your system configuration):
A good source for more information is the article WMIC - Take Command-line Control over WMI by Ethan Wilansky.
Examples of WMIC commands for Windows .NET SERVER Family
Using Windows Management Instrumentation Command-line
And Alain Lissoir's book: Understanding WMI Scripting which devotes an entire chapter to WMIC.
Microsoft Windows 2000 Scripting Guide provides an excellent explanation of WQL use in its chapter "Retrieving Managed Resources Using WMI Query Language".
To create more "selective" queries, use the WMI Query Language, or WQL, a subset of SQL.
See this overview of WQL.