VBScript to start multiple services - vbscript

I need to start multiple services using a VBScript.
I wrote this script to start the services and when I run it, it doesn't give any errors and it doesn't start the services. Any Ideas where the problem might be ?
sComputer = "."
aTargetSvcs= Array ("ServiceOne" &_
"ServiceTwo" &_
"ServiceThree" &_
"ServiceFour")
Set oWMIService = GetObject("winmgmts:" & "{impersonationlevel=impersonate}!\\" _
& sComputer & "\root\cimv2")
Set cServices = oWMIService.ExecQuery("SELECT * FROM Win32_Service")
For Each oService In cServices
For Each sTargetSvc In aTargetSvcs
If LCase(oService.Name) = LCase(sTargetSvc) Then
If oService.State = "Stopped" Then
oService.StartService()
End If
End If
Next
Next

Your aTargetSvcs is not what you think it is - an array containing four strings - but:
Option Explicit
Dim aTargetSvcs : aTargetSvcs = Array ("ServiceOne" &_
"ServiceTwo" &_
"ServiceThree" &_
"ServiceFour")
WScript.Echo UBound(aTargetSvcs)
WScript.Echo aTargetSvcs(UBound(aTargetSvcs))
output:
cscript 21036510.vbs
0
ServiceOneServiceTwoServiceThreeServiceFour

I finally got it to work. I had to use a comma-delimited. Here the change and it works:
However, how can I make each service on its own line to be easy because I have lots of services that I start up. If there is a way to make each service on its own, it would be much easier to read and manage.
sComputer = "."
aTargetSvcs= Array ("ServiceOne","ServiceTwo","ServiceThree")
Set oWMIService = GetObject("winmgmts:" & "{impersonationlevel=impersonate}!\\" _
& sComputer & "\root\cimv2")
Set cServices = oWMIService.ExecQuery("SELECT * FROM Win32_Service")
For Each oService In cServices
For Each sTargetSvc In aTargetSvcs
If LCase(oService.Name) = LCase(sTargetSvc) Then
If oService.State <> "Stopped" Then
oService.StartService()
End If
End if
Next
Next

Related

Stop windows services not listed in input file

I am new to VBS scripting and I am wanting to script the stopping of Windows services other than a core set of services. I have currently written a bit of code that will query all local services and output to a text file their running state, I then wish to read from an input file a list of core services NOT to stop however to stop the rest of the services running on that machine. I would like this to be a generic input file so if a service is listed however is not installed on the server for it to continue onto the next service to stop.
Not sure how to proceed with this, would I need to read the input file into an array then do an IF statement to say if objService.Name not equal to the array (somehow) then to stop the service?
Code below - thanks in advance for any assistance/tips
Const ForAppending = 8
strComputer = "."
strLogPath = "C:\Scripts"
strServicesLog = strLogPath & Replace(Wscript.ScriptName,".vbs","") & ".txt"
Set objWMISvc = GetObject( "winmgmts:\\.\root\cimv2" )
Set colItems = objWMISvc.ExecQuery( "Select * from Win32_ComputerSystem", , 48)
' // Create Output Logs folder for script
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.CreateTextFile(strServicesLog, True)
objTS.Write "******************************************************************" & vbcrlf
objTS.Write (Replace(Wscript.ScriptName,".vbs","") & " audit log") & vbcrlf
objTS.Write ("Execution Start: " & FormatDateTime(Now(),2) & " " &
FormatDateTime(Now(),3)) & vbcrlf
For Each objItem in colItems
strComputerName = objItem.Name
objTS.Write vbCrlf & "Server Name: " & strComputerName & vbCrlf
Next
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery _
("Select * from Win32_Service")
For Each objService in colRunningServices
objTS.Write "Display Name: " & vbTab & (objService.DisplayName) & vbCrlf
objTS.Write "Service Name: " & vbTab & (objService.Name) & vbCrlf
objTS.Write "Service State: " & vbTab & (objService.State) & vbCrlf
objTS.Write "Start Mode: " & vbTab & (objService.StartMode) & vbCrlf
objTS.WriteLine
Next
objTS.Close
You could read your list of services into a Dictionary object. The Dictionary class has an Exists() method that you can use to test if a string/key exists.
Here's how to read a list of strings (services) from a file named c:\input.txt into a dictionary:
Set d = CreateObject("Scripting.Dictionary")
Set objFileIn = objFS.OpenTextFile("c:\input.txt")
Do Until objFileIn.AtEndOfStream
strService = objFileIn.ReadLine()
If Len(strService) > 0 Then If Not d.Exists(strService) Then d.Add strService, ""
Loop
Later, when you're iterating the list of services on the computer, check the service name against your dictionary:
For Each objService in colRunningServices
' If this service is not in the list of core services, stop it...
If Not d.Exists(objService.Name) Then objService.StopService
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

Adding a summary report and disk information to VB Script

I was hoping someone could help me with this code. I wanted to add two things to this script but can't seem to get it working at all.
The script works fine but what isn't working is trying to add the disk information and trying to create a summary report for total size of disk.
at the end of it I'm trying to make an output of what
wmic diskdrive list brief /format:list
would give you.
something like this:
Caption=WDC WD2500BEKT-75PVMT1
DeviceID=\\.\PHYSICALDRIVE0
Model=WDC WD2500BEKT-75PVMT1
Partitions=1
Size=250056737280
Here is the script so far
Option Explicit
const strComputer = "."
const strReport = "c:\path\to\file"
Dim objWMIService, objItem, colItems
Dim strDriveType, strDiskSize, txt
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogicalDisk WHERE DriveType=3")
txt = "Drive" & vbtab & "Size" & vbtab & "Used" & vbtab & "Free" & vbtab & "Free(%)" & vbcrlf
For Each objItem in colItems
DIM pctFreeSpace,strFreeSpace,strusedSpace
pctFreeSpace = INT((objItem.FreeSpace / objItem.Size) * 1000)/10
strDiskSize = Int(objItem.Size /1073741824) & "Gb"
strFreeSpace = Int(objItem.FreeSpace /1073741824) & "Gb"
strUsedSpace = Int((objItem.Size-objItem.FreeSpace)/1073741824) & "Gb"
txt = txt & objItem.Name & vbtab & strDiskSize & vbtab & strUsedSpace & vbTab & strFreeSpace & vbtab & pctFreeSpace & vbcrlf
Next
writeTextFile txt, strReport
wscript.echo "Report written to " & strReport & vbcrlf & vbcrlf & txt
' Procedure to write output to a text file
private sub writeTextFile(byval txt,byval strTextFilePath)
Dim objFSO,objTextFile
set objFSO = createobject("Scripting.FileSystemObject")
set objTextFile = objFSO.CreateTextFile(strTextFilePath)
objTextFile.Write(txt)
objTextFile.Close
SET objTextFile = nothing
end sub
The wmic call and your script do entirely different things. The former queries the Win32_DiskDrive class to gather information about the physical disks, whereas the latter queries the Win32_LogicalDisk class to gather information about the volumes.
You can reproduce the output of the wmic command with something like this:
Set wmi = GetObject("winmgmts://./root/cimv2")
For Each disk In wmi.ExecQuery("SELECT * FROM Win32_DiskDrive")
WScript.Echo "Caption=" & disk.Caption & vbNewLine _
& "DeviceID=" & disk.DeviceID & vbNewLine _
& "Model=" & disk.Model & vbNewLine _
& "Partitions=" & disk.Partitions & vbNewLine _
& "Size=" & disk.Size
Next
However, the size returned by this query is the raw capacity of the physical disk. At this level you can't distinguish if a block is "free" or "used". Those are concepts that apply to filesystems. On that level, a sector either does or doesn't contain one or more files or file fragments. It's "free" when it doesn't contain any file and "used" otherwise. On that level, you don't get any information about "partitions", though, because those exist on a lower level (partitions contain filesystems).
What you need to do is decide which information you actually want to report, and then choose the appropriate properties from the relevant WMI class(es).

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

Using VBScript how can I check if the Spooler service is started and if not start it?

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

Resources