VBScript WMI PnPEntity obtaining HardwareID - vbscript

I'm looking to extract the hardwareID from each device installed on a system using VBScript.
I can extract most properties from the PnPEntity class however the HardwareId or CompatibleId does seem to cause trouble - I'm presuming because it potentially returns an array.
My script is as follows:
Set TxtDriverOutput = objFSO.CreateTextFile("C:\Program Files\xxx\drivers.log", 8, True)
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
txtDriverOutput.WriteLine Now() & Chr(32) & "Begin HardwareID WMI Query"
txtDriverOutput.WriteLine "----------------------------------------------------------------------------"
txtDriverOutput.WriteLine ""
Set colsHardwareID = objWmiService.ExecQuery("Select * from Win32_PnPEntity")
For Each objItem In colshardwareID
For Each StrHardwareID In objItem.HardwareID
txtdriveroutput.WriteLine StrHardwareID
Next
Next
When I run the script, I see one hardware ID populated into the text file - and then I get Error: Object is not a collection flagged on the line of my second for loop (sometimes I have seen it flag the line after it errors for some reason so maybe take that with a pinch of salt.
I have tried using ObjItem.HarwareID.count, UBound(ObjItem.HardwareID) in case there is a PnP Device that doesn't have a hardware ID (not sure if possible). Can anyone point me in the right direction? Thanks!

I managed to get to the bottom of this in the end.
I had to use the following:
For Each objItem In colshardwareID
If Not IsNull(objItem.HardwareID) Then
For Each StrHardwareID In objItem.HardwareID
ReDim Preserve ArrHardwareID(i)
ArrHardwareID(i) = strHardwareID
i = i + 1
Next
End If
Next
As expected - the collection was empty. A .count or .isempty was not working, it had to be IsNull.

Related

How to get MST properties from vbscript

So, I am creating a vbscript that will read an MSI and MST file. The idea is that if the user that will run the script is testing an MSI with an MST file involved, the script should create a "report" of the new properties that this MST have.
I am able to get the properties from a regular MSI, the problem is when I am trying to get into the MST section. While doing research I found out about the _TransformView Table and this should help me to obtain this information but I think I am not sure I know how to handle that table.
Const msiTransformErrorViewTransform = 256
Const msiOpenDB = 2
Dim FS, TS, WI, DB, View, Rec
Set WI = CreateObject("WindowsInstaller.Installer")
Set DB = WI.OpenDatabase(msiPath,msiOpenDB)
DB.ApplyTransform mstPath, msiTransformErrorViewTransform
If Err.number Then
Exit Function
End If
For i = 0 To 24 'Number of properties on the arrPropertyList
Set View = DB.OpenView("Select `Value` From Property WHERE `Property` = " & "'" & arrPropertyList(i) & "'")
View.Execute
Set Rec = View.Fetch
If Not Rec Is Nothing Then
objLog.WriteLine arrPropertyList(i) & " = " & Rec.StringData(1)
End If
Next
That code will display the msi properties that I have added on the arrPropertyList. The thing is that I am looking for the MST properties and I am only getting the MSI ones. I know that I should change the Query to access the _TransformView Table when calling the DB.OpenView but not sure how can I get to this information! Any knowledge you can share would be welcome.
It works slightly differently to what you think. Run the following to see what I mean (maybe force the VBS to run with Cscript.exe from a command prompt if you're expecting a lot of output):
'create 2 constants - one for when we want to just query the MSI (read) and one for when we want to make changes (write)
Const msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact = 1
Const msiTransformErrorViewTransform = 256
'create WindowsInstaller.Installer object
Dim oInstaller : Set oInstaller = CreateObject("WindowsInstaller.Installer")
'open the MSI (the first argument supplied to the vbscript)
Dim oDatabase : Set oDatabase = oInstaller.OpenDatabase("C:\Temp\Temp.msi",msiOpenDatabaseModeReadOnly)
oDatabase.ApplyTransform "C:\Temp\Temp.mst", msiTransformErrorViewTransform
'create a view of the registry we want to see
Dim sql : sql = "SELECT * FROM `_TransformView`"
Dim regView : Set regView = oDatabase.OpenView(sql)
'execute the query
regView.Execute
'fetch the first row of data (if there is one!)
Dim regRecord : Set regRecord = regView.Fetch
'whilst we've returned a row and therefore regRecord is not Nothing
While Not regRecord Is Nothing
'print out the registry key
wscript.echo "Table: " & regRecord.StringData(1)
wscript.echo "Column: " & regRecord.StringData(2)
wscript.echo "Row: " & regRecord.StringData(3)
wscript.echo "Data: " & regRecord.StringData(4)
wscript.echo "Current: " & regRecord.StringData(5)
wscript.echo "***"
'go and fetch the next row of data
Set regRecord = regView.Fetch
Wend
regView.Close
Set regView = Nothing
Set regRecord = Nothing
Set oDatabase = Nothing
Set oInstaller = Nothing
So if you only wanted to see changes in the Property table, you would change the SQL query to:
Dim sql : sql = "SELECT * FROM `_TransformView` WHERE `Table` = 'Property'"
As well as storing the column names of the changed entries, the 'Column' column in the '_TransformView' table also stores whether the value was inserted, removed etc by using the values:
INSERT, DELETE, CREATE, or DROP.
You can find lots of VBScript Windows Installer tutorials for reference - don't forget to set your objects to Nothing otherwise you'll leave handles open. And of course use the link you provided for further reference.
WiLstXfm.vbs: Are you familiar with the MSI SDK sample: wilstxfm.vbs (View a Transform)? It can be used to view transform files. Usage is as follows:
cscript.exe WiLstXfm.vbs MySetup.msi MySetup.mst
Mock-up output:
Property Value [INSTALLLEVEL] {100}->{102}
File DELETE [Help.chm]
I think all you need is in there? Maybe give it a quick look. There is a whole bunch of such MSI API Samples - for all kinds of MSI purposes.
Github.com / Windows SDK: These VBScripts are installed with the Windows SDK, so you can find them on your local disk if you have Visual Studio installed, but you can also find them on Github.com:
Github: WiLstXfm.vbs - Microsoft repository on github.com.
Disk: On your local disk, search under Program Files (x86) if you have Visual Studio installed. Current Example: %ProgramFiles(x86)%\Windows Kits\10\bin\10.0.17763.0\x86.

vbScript that Checks NetworkAdapter Config and updates URL if it detects change

Ok... everyone here seems to be way more educated about this stuff than I. But I've been at this for 2 days straight and I've gone at it from all kinds directions.
Goal:
Have a script check the IP address of local pc. At some time (thinking 5 minutes) recheck the IP address again. Compare the two and if there is a change execute a command silently.
I realize that I can not just get the IP address as I'll get the entire state using winmgmts and I'm ok with that. Really it's just to keep an eye on whether or not the state changes in general. The line of code is to access a URL which will update my FreeDNS incase the IP changes. For whatever reason, none of the programs offered have been working. One even crashes .Net Framework.
Knowing that I'm an utter noob (and thank you for reading this far!) here's what my crazy broken and utterly bizarre code looks like. Any assistance would be divine and I apologize
Dim firstSet, secondSet
Set objWMIService = GetObject("winmgmts:")
Set FirstIP = objWMIService.ExecQuery("SELECT * FROM " & "Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
Set firstSet = FirstIP
WScript.Sleep 3
Set objWMIService = GetObject("winmgmts:")
Set SecondIP = objWMIService.ExecQuery("SELECT * FROM " & "Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
Set secondSet = SecondIP
results = StrComp(firstSet, secondSet, 1)
If Not results = True Then
updateURL = "MyURL"
Set req = CreateObject("MSXML2.XMLHTTP.6.0")
req.Open "GET", updateURL, False
req.Send
End If

VBScript get SNMP OID values

I'm trying to use access SNMP via VBScript to access a few OID values as it's a climate monitor which has figures for temperature, humidity and airflow. I know which OID's I need to use but cannot find any script or piece of code which effectively connects and pulls out out this information.
Has anyone got anything that fits the bill?
I tried using this code but keep getting an error: ActiveX component can't create object: 'Scripting.SNMPManager'
Set oSNMPManager = CreateObject("Scripting.SNMPManager")
oSNMPManager.Agent = "unitip"
oSNMPManager.Community = "public"
'Add Variable objects to Variables collection
Call oSNMPManager.Variables.Add( "1.3.6.1.4.1.17373.2.2.1.6.1" )
Result = oSNMPManager.Get( ErrorIndex )
WScript.Echo "Get result: " & Result
If Result = 10 Then
WScript.Echo "ErrorIndex: " & ErrorIndex
End If
'Display properties of all Variable objects
WScript.Echo "OID, Type, Value"
For Each SNMPVariable in oSNMPManager.Variables
WScript.Echo SNMPVariable.OID & ", " & SNMPVariable.Type & ", " & SNMPVariable.Value
next
'Remove all Variable objects from the Variables collection
oSNMPManager.Variables.RemoveAll
Set objSnmpManager = CreateObject( "AxNetwork.SnmpManager" )
Set objConstants = CreateObject( "AxNetwork.NwConstants" )
' A license key is required to unlock this component after the trial period has expired.
' Call 'Activate' with a valid license key as its first parameter. Second parameter determines whether to save the license key permanently
' to the registry (True, so you need to call Activate only once), or not to store the key permanently (False, so you need to call Activate
' every time the component is created). For details, see manual, chapter "Product Activation".
'
' objSnmpManager.Activate "XXXXX-XXXXX-XXXXX", False

Unlock bitlocker drive with VBScript

I'm trying to script out the unlocking of a bitlocker drive using a DRA certificate. I'm attempting to use the WMI Method UnlockWithCertificateFile and I can't for the life of me figure out what i'm doing wrong or even find an example.
I know the certificate and pin work because i can manually unlock the drive using manage-bde -unlock....
when i run my script i get a return value of -2146885623 wich i've looked up to be -2146885623, "Cannot find the requested object."
i'm not sure what object its talking about.
here is the code i'm using (minus the pin)
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2\Security\MicrosoftVolumeEncryption")
' Obtain an instance of the the class
' using a key property value.
Set objShare = objWMIService.Get("Win32_EncryptableVolume.DeviceID='\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\'")
' Obtain an InParameters object specific
' to the method.
Set objInParam = objShare.Methods_("UnlockWithCertificateFile"). _
inParameters.SpawnInstance_()
' Add the input parameters.
objInParam.Properties_.Item("PathWithFileName") = "D:\BitLocker.pfx"
objInParam.Properties_.Item("Pin") = "PinCode
' Execute the method and obtain the return status.
' The OutParameters object in objOutParams
' is created by the provider.
Set objOutParams = objWMIService.ExecMethod("Win32_EncryptableVolume.DeviceID='\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\'", "UnlockWithCertificateFile", objInParam)
' List OutParams
Wscript.Echo "Out Parameters: "
Wscript.echo "ReturnValue: " & objOutParams.ReturnValue
has anyone ever used this method or can anyone see something i may be doing wrong? also i'm using the windows 8 commandline recovery option, i'm not sure if that makes a difference because i have tested calling other methods and wmi and scripting seem to be fully implemented.

Two different names for Windows services (VB6)

I am having a minor problem automating the starting and stopping of services. When I open services.msc and look at the list of services, they all have names. However, when I run this code:
Dim objService As Object
Dim objSet As Object
IsServiceRunning = False
Set objSet = GetObject("winmgmts:").ExecQuery("SELECT * FROM Win32_Service")
For Each objService In objSet
If (UCase(strServiceName) = UCase(objService.Name)) And (UCase(objService.State) = UCase("Running")) Then
IsServiceRunning = True
End If
Next
The objService.Name value is not the same as the name in the list. For example, "Computer Browser" is just "browser", "Distributed File System" is "dfs", and "Net Logon" is "netlogon". Is there a way to pull the full, longer name for these services from this objService object? I can workaround this, but for the sake of clarity in the code I'd rather use the same value for determining if the service is running, making a NET START or NET STOP command line call, and logging.
Just use objService.Caption to access "long name" of service.
I discovered the name of the property like this:
For Each objService In objSet
For Each vElem In objService.Properties_
Debug.Print vElem.Name; "=";
Debug.Print vElem.Value
Next
Exit For
...
Next
Just put objService in watch window to find out Properties_ property. Put vElem in watch window too to find Name and the default property Value (besides IsArray, etc.) of SWbemProperty object.

Resources