VBS: How to store all Win32_OS (WMI) queries to dictionary

January 15, 2018 at 06:41:24
Specs: Windows
VBScript > Scripting.Dictionary

Using VBScript

How do you retrieve all queries from Win32_OperatingSystem (via WMI) then store them in a dictionary?


So i can get for example "Caption", "Name" & "BuildNumber" from the dictionary instead of keep querying Win32_OperatingSystem

message edited by 38956


See More: VBS: How to store all Win32_OS (WMI) queries to dictionary

Report •

#1
January 16, 2018 at 02:04:59
I got this for you, it's in batch tho:

::----start of test.bat----
@echo off&echo off>output.txt
::created empty file
for /f "tokens=1 delims=|" %%a in ('WMIC OS GET Name ^| findstr "Windows"') do echo "OSname","%%a">>output.txt
for /f "tokens=1 delims=|" %%a in ('WMIC OS GET CSDVersion ^| findstr "Service"') do echo "CSDversion","%%a">>output.txt
for /f "tokens=1" %%a in ('wmic os get osarchitecture ^| findstr "bit"') do echo "arch","%%a">>output.txt
::some of the answers depending on the OS might not give a reply to these wmic lookups
exit /b
::----end of test.bat----

i5-6600K@4.670GHz/4.448GHz cache@1.33v | 2x4GB Crucial-DDR4-2133@ 15-15-15-31 2T 2817MHz@1.3v | ASUS Z170-K | Samsung 250GB SSD 850 EVO | MSI RX 570 4GB@1366cc&2120mc bios-powertune-mod | Corsair VS45


Report •

#2
January 25, 2018 at 09:56:42
There's missing context here. Most people are only going to have one instance of an OS running on a system at once. In which case, you can just save and query the object directly as much as you need.

Set os = GetObject("winmgmts:Win32_OperatingSystem=@")
WScript.Echo os.Caption & vbNewLine & os.Name & vbNewLine & os.BuildNumber

How To Ask Questions The Smart Way


Report •

#3
January 25, 2018 at 19:47:49
I think he wants the whole ball of wax ( the "caption" and "name" etc were just examples (?)) to save time. Some queries, on my old system, take 2 or 3 seconds to complete. Trade-off is of course updating on a regular basis.

message edited by nbrane


Report •

Related Solutions

#4
January 26, 2018 at 06:14:20
Well generally, once you have a WMI object, its properties are static. For instance, you can save a query for Win32_Process, and any further changes in those processes, including termination, are not reflected in those Win32_Process objects you're holding.

How To Ask Questions The Smart Way


Report •

#5
February 3, 2018 at 05:37:38
You can do something like this in vbscript :
' List Operating System Properties
Set dtmConvertedDate = CreateObject("WbemScripting.SWbemDateTime")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

For Each objOperatingSystem in colOperatingSystems
msg = msg & "Boot Device: " & objOperatingSystem.BootDevice & vbcrlf
msg = msg & "Build Number: " & objOperatingSystem.BuildNumber & vbcrlf
msg = msg &  "Build Type: " & objOperatingSystem.BuildType & vbcrlf
msg = msg &  "Caption: " & objOperatingSystem.Caption & vbcrlf
msg = msg &  "Code Set: " & objOperatingSystem.CodeSet & vbcrlf
msg = msg &  "Country Code: " & objOperatingSystem.CountryCode & vbcrlf
msg = msg &  "Debug: " & objOperatingSystem.Debug & vbcrlf
msg = msg &  "Encryption Level: " & objOperatingSystem.EncryptionLevel & vbcrlf
dtmConvertedDate.Value = objOperatingSystem.InstallDate
dtmInstallDate = dtmConvertedDate.GetVarDate
msg = msg &  "Install Date: " & dtmInstallDate & vbcrlf
msg = msg &  "Licensed Users: " & _
objOperatingSystem.NumberOfLicensedUsers & vbcrlf
msg = msg &  "Organization: " & objOperatingSystem.Organization & vbcrlf
msg = msg &  "OS Language: " & objOperatingSystem.OSLanguage & vbcrlf
msg = msg &  "OS Product Suite: " & objOperatingSystem.OSProductSuite & vbcrlf
msg = msg &  "OS Type: " & objOperatingSystem.OSType & vbcrlf
msg = msg &  "Primary: " & objOperatingSystem.Primary & vbcrlf
msg = msg &  "Registered User: " & objOperatingSystem.RegisteredUser & vbcrlf
msg = msg &  "Serial Number: " & objOperatingSystem.SerialNumber & vbcrlf
msg = msg &  "Version: " & objOperatingSystem.Version
Next
wscript.echo msg

Code inspired from this link List Operating System Properties

Report •

#6
February 3, 2018 at 08:33:38
First of all, I already did VBScript back in #2. Second of all, computers exist to make our lives easier. Don't work the computer, make the computer work for you.
Set os = GetObject("winmgmts:Win32_OperatingSystem=@")
Set props = CreateObject("System.Collections.ArrayList")
For Each p In os.Properties_
  If Not p.IsArray Then _
    props.Add p.Name & ": " & p.Value
Next 'p
WScript.Echo Join(props.ToArray, vbNewLine)

How To Ask Questions The Smart Way


Report •

#7
February 4, 2018 at 07:23:57
Here is another script using a Dictionary and saving the result into a LogFile

Option Explicit
Dim ws,fso,LogFile,OS,oDic,p,Key,msg
set ws = CreateObject("wscript.shell")
Set fso = CreateObject("Scripting.FileSystemObject")
LogFile = Left(Wscript.ScriptFullName, InstrRev(Wscript.ScriptFullName, ".")) & "txt"
If fso.FileExists(LogFile) Then
        fso.DeleteFile LogFile
End If

Set OS = GetObject("winmgmts:Win32_OperatingSystem=@")
Set oDic = CreateObject("scripting.dictionary")
For Each p In OS.Properties_
	If Not p.IsArray Then oDic.Add p.Name,p.Value
Next

For Each key in oDic.Keys
	msg = msg & key & " : " & oDic(key) & vbcrlf
Next

Call WriteLog(msg,LogFile)
ws.run LogFile
'************************************************************
Sub WriteLog(strText,LogFile)
    Dim fs,ts
    Const ForWriting = 2
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set ts = fs.OpenTextFile(LogFile,ForWriting,True)
    ts.WriteLine strText
    ts.Close
End Sub
'************************************************************


Report •

#8
June 16, 2018 at 13:04:38
Option Explicit
Dim ws,fso,LogFile,OS,dicWin32OS,p,Key,msg
set ws = CreateObject("wscript.shell")
Set fso = CreateObject("Scripting.FileSystemObject")
LogFile = Left(Wscript.ScriptFullName, InstrRev(Wscript.ScriptFullName, ".")) & "txt"
If fso.FileExists(LogFile) Then
        fso.DeleteFile LogFile
End If

  cDicWin32OS ' Create Dictionary

For Each key in dicWin32OS.Keys
	msg = msg & key & " : " & dicWin32OS(key) & vbcrlf
Next

Call WriteLog(msg,LogFile)
ws.run LogFile
'************************************************************
Sub WriteLog(strText,LogFile)
    Dim fs,ts
    Const ForWriting = 2
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set ts = fs.OpenTextFile(LogFile,ForWriting,True)
    ts.WriteLine strText
    ts.Close
End Sub
'************************************************************

Sub cDicWin32OS
 Set OS = GetObject("winmgmts:Win32_OperatingSystem=@")
 Set dicWin32OS = CreateObject("scripting.dictionary")

  For Each p In OS.Properties_
	If Not p.IsArray Then dicWin32OS.Add p.Name,p.Value
  Next

End Sub

Why doesn't this work for Win32_ComputerSystem as well?

I want to do the same thing to these as well (See below)

Win32_OperatingSystem    (dicWin32OS)
Win32_ComputerSystem      (dicWin32CS)
Win32_ComputerSystemProduct  (dicWin32CSP)
Win32_BaseBoard			(dicWin32BB)
Win32_BIOS			(dictWin32BIOS)


In the past i've used the following to retrieve information from Win32 classes (OperatingSystem, ComputerSystem ect..)


(short example)

Option Explicit
Dim strComputer,strUsername,strPwd
Dim objSWbemLocator,objSWbemServices,objWMIService,objShell,oReg
Dim colOS,colCS,colCSP,colBB,colBIOS
Dim objOS, objCS
Dim strOSCaption,strOSSKU,strOSArchitecture,strCSManufacturer,strCSModel
 strComputer = "."
 strUsername = ""
 strPwd = ""

        Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") 
        Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\default", strUsername, strPwd)

        Set objWMIService = objSWbemLocator.ConnectServer(strComputer, "root\cimv2", strUsername, strPwd)
            objWMIService.Security_.ImpersonationLevel = 3
        Set objShell = CreateObject("WScript.Shell")

        Set oReg = objSWbemServices.Get("StdRegProv")


    Set colOS  = objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem",,48)
    Set colCS  = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem",,48)
    Set colCSP = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct",,48)
    Set colBB  = objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard",,48)
    Set colBIOS  = objWMIService.ExecQuery("SELECT * FROM Win32_BIOS",,48)

     For Each objOS in colOS 

        strOSCaption = objOS.Caption
        strOSSKU = objOS.OperatingSystemSKU
        strOSArchitecture = objOS.OSArchitecture ' OS Architecture

   Next

      For Each objCS in colCS
         strCSManufacturer = objCS.Manufacturer
         strCSModel = objCS.Model
   Next
   
   WScript.Echo "OS.Caption: " & vbTAB & strOSCaption & vbCR _
    & "OS SKU: " & vbTAB & vbTAB & strOSSKU & vbCR _
	& "OS Architecture: " & vbTAB & strOSArchitecture & vbCR & vbCR _
	& "CS Manufacturer: " & vbTAB & strCSManufacturer & vbCR _
	& "CS Model: " & vbTAB & strCSModel


Thanks for the help i've had so far

message edited by 38956


Report •

#9
June 17, 2018 at 07:01:42
Example
[1a] Querying all Win32_OperatingSystem
[1b] Create dictionary (dicWin32OS) and add Name and Value to dictionary
[2a] Querying all Win32_ComputerSystem
[2b] Create dictionary (dicWin32CS) and add Name and Value to dictionary
[3a] Query dictionary (dicWin32OS) for Key named "Caption" get value
[3b] Query dictionary (dicWin32CS) for Key named "Manufacturer" get value

Do same for

Win32_ComputerSystem (dicWin32CS)
Win32_ComputerSystemProduct (dicWin32CSP)
Win32_BaseBoard (dicWin32BB)
Win32_BIOS (dicWin32BIOS)


Create all dictionaries using separate subs first


Post #7 by Hackoo

I changed Win32_OperatingSystem to Win32_ComputerSystem on the script posted (Post #7) by Hackoo and when i try it i get an error

What am I doing wrong?

[ Thanks in advance to anyone who can help. ]

message edited by 38956


Report •

#10
June 19, 2018 at 06:05:10
You'll notice Hackoo used the same WMI object grabbing I used, and I'm lazy. Lazy enough that if I know where you live, I won't put your address into Google Maps whenever I'm stopping by. WMI's the same way. Everyone will have Win32_ComputerSystem at "@". I can just go and get it without having to look that up. So I did. The other classes you list do not work that way. You'll have to do the traditional lookups.

Good luck with your homework

How To Ask Questions The Smart Way


Report •

Ask Question