What is use of line:
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
in vbscript code.
This will create a WMI object that provides you with the objects, methods and properties needed to be able to communicate with the different parts of the OS.
So, using your snippet, you could for example query the status of every service:
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service")
For Each objService in colRunningServices
MsgBox objService.Name & " - " & objService.State
Next
You aren't limited to services, you can access registry settings, active process, etc. I use it often at work to help manage our Windows environment.
A few resources:
http://msdn.microsoft.com/en-us/library/aa394585(v=vs.85).aspx
http://technet.microsoft.com/en-us/library/ee176998.aspx
Related
I've had to do a little VBScript recently, and many scripts that I've seen use this variable strComputer which, on the surface anyway, seems pointless. It's typically set to ".", and then used in a string concatenation like so:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Why is this done, when one could simply write Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")? I see this all over the place and it mystifies me.
As #false pointed out in the comments to the question, the purpose is to make the computer whose WMI service you want to access configurable.
. is a shortcut for the local computer. If you're certain that your script will only ever be connecting to the local computer there is indeed no benefit to be gained from a configurable computername, and you're better off just merging the . into the moniker:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
However, if you need the ability to run the script against remote hosts, you can for instance make the host configurable via a commandline argument:
strComputer = "." 'default to localhost
If WScript.Arguments.Exists("ComputerName") Then
strComputer = WScript.Arguments.Named("ComputerName")
End If
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
'do stuff with objWMIService
or read a list of hostnames from a file:
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("C:\computerlist.txt")
Do Until f.AtEndOfStream
strComputer = f.ReadLine
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
'do stuff with objWMIService
Loop
f.Close
I'd like to use VBScript to check if the Spooler service is started and if not start it, the code below checks the service status but I need some help modifying this so I can check if it is started.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery _
("Select * from Win32_Service")
For Each objService in colRunningServices
Wscript.Echo objService.DisplayName & VbTab & objService.State
Next
Many thanks
Steven
How about something like this. This command will start it if it isn't already running. No need to check in advance.
Dim shell
Set shell = CreateObject("WScript.Shell")
shell.Run "NET START spooler", 1, false
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery _
("select State from Win32_Service where Name = 'Spooler'")
For Each objService in colRunningServices
If objService.State <> "Running" Then
errReturn = objService.StartService()
End If
Next
Note you can also use objService.started to check if its started.
Just for the completeless, here's an alternative variant using the Shell.Application object:
Const strServiceName = "Spooler"
Set oShell = CreateObject("Shell.Application")
If Not oShell.IsServiceRunning(strServiceName) Then
oShell.ServiceStart strServiceName, False
End If
Or simply:
Set oShell = CreateObject("Shell.Application")
oShell.ServiceStart "Spooler", False ''# This returns False if the service is already running
Is there a way to retrieve the voltage being supplied to a computer in real time?
You can use WMI to get some of that information. I used the WMI Code Creator to come up with this VB script which returns the Win32_Processor CurrentVoltage value. If you have a laptop, there is also some battery information available in WMI.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Processor",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Win32_Processor instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "CurrentVoltage: " & objItem.CurrentVoltage
Next
I have this VBScript code to terminate one process
Const strComputer = "."
Dim objWMIService, colProcessList
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'Process.exe'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
It works fine with some processes, but when it comes to any process runs under SYSTEM, it can't stop it.
Is there is anything I need to add to kill the process under SYSTEM?
The way I have gotten this to work in the past is by using PsKill from Microsoft's SysInternals. PsKill can terminate system processes and any processes that are locked.
You need to download the executable and place it in the same directory as the script or add it's path in the WshShell.Exec call. Here's your sample code changed to use PsKill.
Const strComputer = "."
Set WshShell = CreateObject("WScript.Shell")
Dim objWMIService, colProcessList
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'Process.exe'")
For Each objProcess in colProcessList
WshShell.Exec "PSKill " & objProcess.ProcessId
Next
Try explicit assert debug privilege {impersonationLevel=impersonate,(debug)}:
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate,(debug)}!\\.\root\CIMV2")
Set procs = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name='SearchIndexer.exe'", , 48)
For Each proc In procs
proc.Terminate
Next
at this point i get error message:
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Error: Invalid procedure call or Argument: "GetObject"
Code: 800A005
Source: Microsoft VBScript Runtime error
Complete rewrite.
Here is the code generated by WMI Code Creator, with very minor editing.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_ComputerSystem",,48)
For Each objItem in colItems
MsgBox "CurrentTimeZone: " & objItem.CurrentTimeZone
Next