Using WMI objects in VB script to decide which programs to run - vbscript

I have a vbscript that will find the OS, Service pack and OS Architecture but when i try to use the object in a If then statement its not defined, I tried to declare it but that didn't work. What i am trying to complete is create a script that will define the OS, Service pack and whether the system is x86 or x64 and the execute a program that will install the updates specific for that system but I'm stuck.
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
Wscript.Echo "Version: " & objOperatingSystem.Version
Wscript.Echo "Service Pack: " & objOperatingSystem.CSDVersion
Wscript.Echo "CPU Bit: " & objOperatingSystem.OSArchitecture
Next

I am assuming you are not storing those variables you are echoing with "wscript.echo"..
You could use this example (or make a case statement):
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
osVersion = objOperatingSystem.Version
osCSDVersion = objOperatingSystem.CSDVersion
osArchitecture = objOperatingSystem.OSArchitecture
Next
Wscript.Echo "Version: " & osVersion
Wscript.Echo "Service Pack: " & osCSDVersion
Wscript.Echo "CPU Bit: " & osArchitecture
If InStr(LCase(osArchitecture), "64-bit") Then
wscript.echo "64-bit"
' .... Do stuff here ....
Else
wscript.echo "not 64-bit"
' .... Do stuff here ....
End If

Related

How to handle unavailable computers in WMI connections?

I want to assess the memory and other details of computers connected to my domain. What I am doing is writing the computer name in a text file, one per line. the Script will read the file (hostname) one by one, gather the information, and write it to a file. This is working fine.
Problem is that if one computer is not available then it's making problems. For example, if first host name is available and second is not available, then it keeps showing the same information repeatedly.
INPUT_FILE_NAME = "D:\tmp\Computer.txt"
Const FOR_READING = 1
Const HKEY_LOCAL_MACHINE = &H80000002
strRegKey = "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(INPUT_FILE_NAME, FOR_READING)
strComputers = objFile.ReadAll
objFile.Close
arrComputers = Split(strComputers, vbCrLf)
For Each strComputer In arrComputers
On Error Resume Next
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
"//./root/default:StdRegProv")
objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colPageFiles = objWMIService.ExecQuery _
("Select * from Win32_PageFileUsage")
For each objPageFile in colPageFiles
Wscript.Echo "Host Name: " & strHostName, _
"AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
"CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
"Description: "& vbTab & objPageFile.Description, _
"InstallDate: "& vbTab & objPageFile.InstallDate, _
"Name: " & vbTab & objPageFile.Name, _
"PeakUsage: " & vbTab & objPageFile.PeakUsage
Next
Next
When GetObject() fails, the variable objWMIService retains its previous value, so you're reporting the same host over and over again, until either GetObject() can connect to a host or the loop terminates. Change this:
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colPageFiles = objWMIService.ExecQuery _
("Select * from Win32_PageFileUsage")
For each objPageFile in colPageFiles
Wscript.Echo "Host Name: " & strHostName, _
"AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
"CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
"Description: "& vbTab & objPageFile.Description, _
"InstallDate: "& vbTab & objPageFile.InstallDate, _
"Name: " & vbTab & objPageFile.Name, _
"PeakUsage: " & vbTab & objPageFile.PeakUsage
Next
into this:
Set objWMIService = Nothing
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Not objWMIService Is Nothing Then
Set colPageFiles = objWMIService.ExecQuery _
("Select * from Win32_PageFileUsage")
For each objPageFile in colPageFiles
Wscript.Echo "Host Name: " & strHostName, _
"AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
"CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
"Description: "& vbTab & objPageFile.Description, _
"InstallDate: "& vbTab & objPageFile.InstallDate, _
"Name: " & vbTab & objPageFile.Name, _
"PeakUsage: " & vbTab & objPageFile.PeakUsage
Next
Else
WScript.Echo strComputer & " unavailable."
End If
and the problem will disappear.
On a different note, the first 2 lines in the outer loop will always retrieve the hostname of your local computer:
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
"//./root/default:StdRegProv")
objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname
If that's what you actually want, you should move the code outside the loop, because the value of strHostname won't change:
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
"//./root/default:StdRegProv")
objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname
For Each strComputer In arrComputers
'...
Next
If you actually want the name of the remote computer (which would make a lot more sense when the rest of the information is from the remote computer as well), you could simply use strComputer and remove the registry query entirely.

Getting Volume Serial Number Of Script Location

here is a vbscript which shows all drives' volume serial numbers. But I need to customize to return only the volume serial number of the drive which the script is running from.
How to do it?
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
str = ""
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk")
For Each objItem In colItems
str = str & objItem.Name & " SerialNumber: " & objItem.VolumeSerialNumber & vbCrlf & vbCrlf
Next
MsgBox str
This should do what you need:
' Get the drive designator...
With CreateObject("Scripting.FileSystemObject")
strDrive = .GetDriveName(WScript.ScriptFullName)
End With
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceId='" & strDrive & "'")
' There should only be one item in the collection...
For Each objItem In colItems
MsgBox objItem.Name & " SerialNumber: " & objItem.VolumeSerialNumber
Next

Getting Script Name from wscript.exe Process

I am using this code:
Dim name
name = CreateObject("WScript.Shell").ExpandEnvironmentStrings("%computername%")
Set wmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& name & "\root\cimv2")
For Each hwnd In wmi.InstancesOf("Win32_Process")
If hwnd.Name = "wscript.exe" Then
'get name and possibly location of currently running script
End If
Next
I am successfully listing all processes and picking out the wscript.exe. However, I have searched and have found no way to find the name of the script running in wscript.exe, ie. is it myscript.vbs or jscript.js or anything. Bonus if there is a way to find the whole path of the script.
EDIT:
With more searching, I found a solution. In the above script, the hwnd variable stores the handle for the wscript.exe process. There is a property for handles: hwnd.CommandLine. It shows how to call it from the command line, so it would be something like:
"C:\Windows\System32\wscript.exe" "C:\path\to\script.vbs"
So I can parse the hwnd.CommandLine string to find the path and name of all running scripts.
You have ScriptName and ScriptFullName properties.
' in VBScript
WScript.Echo WScript.ScriptName
WScript.Echo WScript.ScriptFullName
// in JScript
WScript.Echo(WScript.ScriptName);
WScript.Echo(WScript.ScriptFullName);
[EDIT] Here you go (use .CommandLine property):
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& "." & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery( _
"Select * from Win32_Process " _
& "Where Name = 'WScript.exe'", , 48)
Dim strReport
For Each objProcess in colProcesses
' skip current script, and display the rest
If InStr (objProcess.CommandLine, WScript.ScriptName) = 0 Then
strReport = strReport & vbNewLine & vbNewLine & _
"ProcessId: " & objProcess.ProcessId & vbNewLine & _
"ParentProcessId: " & objProcess.ParentProcessId & _
vbNewLine & "CommandLine: " & objProcess.CommandLine & _
vbNewLine & "Caption: " & objProcess.Caption & _
vbNewLine & "ExecutablePath: " & objProcess.ExecutablePath
End If
Next
WScript.Echo strReport
myProcess="wscript.exe"
Set Processes = GetObject("winmgmts:").InstancesOf("Win32_Process")
For Each Process In Processes
If StrComp(Process.Name, myProcess, vbTextCompare) = 0 Then 'check if process exist
CmdLine=process.commandline
End If
Next
myArr=split(CmdLine,"\")
mySN=replace(myArr(ubound(myArr)),"""","")
Wscript.Echo "Full Pth: " & Cmdline &vbcrlf&"Script Name: "& mySN

Basic VBS help - optimizing VBS script

I found this simple script that outputs the logical disk sizes.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For Each objDisk in colDisks
Wscript.Echo "DeviceID: " & objDisk.DeviceID & " with a Disk Size: " & objDisk.Size
Next
My VBS skills are very poor and I need help:
I would like to get a single size number of ONLY the C and D partitions added together
if the size (from step1) is not equal to 500-GB (between 450,000,000,000 and 550,000,000,000) I need the computer to prompt a warning and "press any key" to continue
I don't want a pop-up window since this is going to run from the prompt of WinPE, is it possible to get the output in the prompt window?
I'm asking a lot so thank you in advance if you can help
You will need to start your script using cscript.
The code for this comes from http://ask.metafilter.com/79481/vbscript-printing-to-command-line
This allows the echos to go to the command line instead of a Message box.
CheckStartMode
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For Each objDisk in colDisks
If(objDisk.DeviceID="C:" or objDisk.DeviceID="D:") then
Wscript.Echo "DeviceID: " & objDisk.DeviceID & " with a Disk Size: " & objDisk.Size
TotalSize = CCur(TotalSize) + CCur(objDisk.Size)
End if
Next
If(TotalSize <450000000000 or TotalSize >550000000000) then
Wscript.Echo "Disk size of " & TotalSize & " is out of range."
Wscript.Echo "Press enter to contine."
z = WScript.StdIn.Read(1)
End if
Wscript.Echo "Complete, Press enter to end."
z = WScript.StdIn.Read(1)
Sub CheckStartMode
' Returns the running executable as upper case from the last \ symbol
strStartExe = UCase( Mid( wscript.fullname, instrRev(wscript.fullname, "\") + 1 ) )
If Not strStartExe = "CSCRIPT.EXE" Then
' This wasn't launched with cscript.exe, so relaunch using cscript.exe explicitly!
' wscript.scriptfullname is the full path to the actual script
set oSh = CreateObject("wscript.shell")
oSh.Run "cscript.exe """ & wscript.scriptfullname & """"
wscript.quit
End If
End Sub

Obtaining process that launched (for instance) iexplore with VBScript/JScript

Is there a way to (ideally with a scripting language like VBScript / JScript) get details of a process that spawned a different program i.e., In the case when Computrace LoJack launches iexplore, to handle communications with the internet?
You can use WMI to check the ParentProcessId for the process you are interested in. In the case of "normal" user mode applications, the parent process should be explorer.exe.
strProcess = "iexplore.exe"
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = '" & strProcess & "'")
For Each objProcess in colProcesses
WScript.Echo objProcess.ParentProcessId
Next
In the case of Internet Explorer, make sure you check for the ID of IE as well since it will spawn multiple instances of itself. Try something like this:
strProcess = "iexplore.exe"
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = 'explorer.exe' OR name = 'iexplore.exe'")
i = 0
arrIds = Array()
For Each objProcess in colProcesses
ReDim Preserve arrIds(i)
arrIds(i) = objProcess.ProcessId
i = i + 1
Next
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = '" & strProcess & "'")
For Each objProcess in colProcesses
intParentID = objProcess.ParentProcessId
blnIsFound = False
For Each intID in arrIds
If intID = intParentID Then
blnIsFound = True
Exit For
End If
Next
If blnIsFound = False Then
WScript.Echo "Process " & objProcess.ProcessId & " spawned by process " & objProcess.ParentProcessId
End If
Next

Resources