VBScript to stop service works in WinXP not in Win7 - vbscript

I have a boot script that copies some ini files, based on the OS being used, for MySQL Server. The script works fine on WinXP but in Win7 it does not stop the service. No error is reported. The script appears to run fine except for the fact that the ini files are not copied if the service is running.
I have removed the stop service portion of the code and placed it in a script by itself. However, it still works on WinXP and not on Win7.
Can anyone see any reason for the script not working?
Sub StopService(computerName, serviceName)
Dim service
Set service = GetService(computerName, serviceName)
If(service Is Nothing) Then
Call Log.Warning("The " & serviceName & " service on the " & computerName & " computer was not found")
Else
service.StopService()
End If
End Sub
Function GetService(computerName, serviceName)
Dim wmiService, objectsList, eObjectsList, ObjService, item, sysID
Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & computerName & "\root\cimv2")
Set objectsList = wmiService.ExecQuery("Select * from Win32_Service Where Name = '" & serviceName & "'")
For Each ObjService in objectsList
If(ObjService.Name = serviceName) Then
Set GetService = ObjService
Exit Function
End If
Next
Set GetService = Nothing
End Function
StopService ".", "MySQL56"
Thanks for any and all help,
Charles

Related

Get running instance of application from WMI process?

I'm trying to get hold of running instances of MS Access 2010+ (on Win10) but the usual tip; GetObject(, "Access.Application") ... for works only for hidden instances started by myself with script, but not any instances started from GUI by the user.
And yes, I've read perhaps ten or more google hits on the subject, both on WMI and GetObject, but I seem to have missed something important.
However, I've tried the code below and I can get hold of any process of running Access instances in this way, and I can even .terminate() them, but, that's not what I want to do. Instead I want to grab the process and assign it to a usable (correct type) Access variable (see "OutInstance" in the code below) :
[Edit: Using WHERE clause, and skipped Exit as to retrieve the last instance]
Public Function GetRunningInstance(sAppName sComputer, ByRef OutInstance)
Dim oWMIService
Dim wProcesses
Dim oPrc
GetRunningInstance = False
Set OutInstance = Nothing
if sComputer = "" then sComputer = "."
Set oWMIService = GetObject("winmgmts:" & "{impersonationLevel=" & _
"impersonate}!\\" & sComputer & "\root\cimv2")
Set wProcesses = oWMIService.ExecQuery ("SELECT * FROM Win32_Process " & _
"WHERE Name = '" & sAppName & "'")
For Each oPrc in wProcesses
''' oPrc.Terminate() ''' Works, I can shut down Access...
Set OutInstance = oPrc
GetRunningInstance = True
''' By not exiting we get the last instance.
Next
End Function
Now, after trying to get hold of an instance, how do I "cast" the process to a usable Access application variable in this VBScript?
Sub Test_DoStuff()
Dim InstProc
Dim AccessApp
If GetRunningInstance("msaccess.exe", "127.0.0.1", InstProc) Then
Set AccessApp = ''' cast 'InstProc' to my "Access.Application" somehow?
Else
Set AccessApp = CreateObject("Access.Application")
End If
'''
''' Doing my stuff
'''
AccessApp.CloseCurrentDatabase
AccessApp.DoCmd.Quit
End Sub
Test
I (also) don't understand why GetObject(, "Access.Application") doesn't work in all cases. Permissions? (I understand that it's 'unsafe' to close a database currently being used by a user, but also that can be dealt with).
// Rolf

VBScript Strange Issue with HTA and Type mismatch error

When I run the following script on it's own by double clicking, it works just fine. It returns the last logged on user as expected. But when I run it from the HTA I have been developing as a front end to all of my scripts, I get a type mismatch error on the "wscript.echo strvalue" line. I have tried everything to get it to work, like changing permissions on mshta.exe to full control for myself. I simply can't get it to run from the HTA without getting an error, but it works 100% as expected on its own. I am completely stumped.
strinput = "myserver"
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strinput & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI"
strValueName = "LastLoggedOnUser"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
Wscript.Echo strValue
By default, Windows 64-bit uses MSHTA.EXE 32-bit. The registry has a separate branches for 64-bit and 32-bit apps, thus WMI can't find the registry value you are looking for.
Save the code below to e. g. C:\test\tmp.hta, try to launch it from explorer by double-click (32-bit by default) - you will get null, and then launch via Run dialog (Win+R) with path: %windir%\system32\mshta.exe "C:\test\tmp.hta" (64-bit), the result will be your username.
<html>
<head>
<script language="vbscript">
Sub window_onload()
Const HKEY_LOCAL_MACHINE = &H80000002
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI"
strValueName = "LastLoggedOnUser"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
document.body.innerText = strValue
End Sub
</script>
</head>
<body>
</body>
</html>
Note that many other stuff within scripts depends on application architecture, e. g. number of ActiveX are available only in 32-bit version, so they should be launched via %windir%\SysWOW64\ (Windows 32-bit on Windows 64-bit subsystem).
Use Msgbox function instead of Wscript.Echo method. HTAs use the Internet Explorer Scripting Object Model which does not contain Wscript object (this belongs to Windows Script Host Object Model).
Read HTA: Why Can’t I Use Wscript.Echo?:
You might have noticed that when it came time to report back the
operating system version we used the VBScript Msgbox function rather
than the more common Wscript.Echo. Why didn’t we use Wscript.Echo?
Here’s why:
As it turns out the various Wscript methods - Wscript.Echo,
Wscript.Sleep, Wscript.Quit, etc. - are designed solely to run under
the Windows Script Host environment. When we’re working in an HTA
we’re not running under WSH; instead we’re running under the MSHTA
process. Because of that the Wscript methods are not available to us
(nor can we create them). Consequently we need to find workarounds for
each method, and Msgbox is a perfectly adequate replacement for
Wscript.Echo. (We’ll talk about workarounds for other methods - such
as Wscript.Sleep - when we get to them.)
The moral of the story: Don’t bother with Wscript.Echo; it won’t work.
Edit: with Wscript.Echo TypeName(strValue) & vbNewLine & VarType(strValue):
==> C:\Windows\System32\cscript.exe D:\VB_scripts\SO\33505295.vbs
String
8
==> C:\Windows\SysWOW64\cscript.exe D:\VB_scripts\SO\33505295.vbs
Null
1
Tried in a simple HTA which gives the same (different) result
==> C:\Windows\System32\mshta.exe 33505295.hta
versus
==> C:\Windows\SysWOW64\mshta.exe 33505295.hta
Conclusion. Check HTA file type association. For instance, ftype htafile in my Windows 8 (64bit) returns (surprisingly?) the same value which causes wrong behaviour on double click:
==> assoc .hta
.hta=htafile
==> ftype htafile
htafile=C:\Windows\SysWOW64\mshta.exe "%1" {1E460BD7-F1C3-4B2E-88BF-4E770A288AF5}%U{1E460BD7-F1C3-4B2E-88BF-4E770A288AF5} %*
I have had the same challenge a few weeks ago.
The following code provided me the possibility to see who is currently logged onto a remote computer.
I hope this can help you.
Sub ActionGetCurrentUser(strCPU) 'strCPU is the computername
set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strCPU & "\root\cimv2")
set Items = objWMI.ExecQuery("Select * From Win32_ComputerSystem")
For Each obj in Items
OutStr = right(obj.username,9)
Next
Resultstring = "Logged in User is: " & OutStr
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strTarget = "LDAP://" & strDNSDomain
' ---------------- Write the User's account & password to a variable -------------------
strCurrentuser = Currentuser.value
strPassword = PasswordArea.value
' ---------------- Connect to Ad Provider ----------------
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Properties("User ID") = strCurrentUser ' pass credentials - if you omit this, the search is performed....
objConnection.Properties("Password") = strPassword ' ... with the current credentials
objConnection.Properties("Encrypt Password") = True ' only needed if you set "User ID" and "Password"
objConnection.Open "Active Directory Provider"
Set objCmd = CreateObject("ADODB.Command")
Set objCmd.ActiveConnection = objConnection
objCmd.CommandText = "SELECT DisplayName FROM '" & strTarget & "' WHERE extensionAttribute11 = '" & OutStr & "'"
Const ADS_SCOPE_SUBTREE = 2
objCmd.Properties("Page Size") = 100
objCmd.Properties("Timeout") = 30
objCmd.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCmd.Properties("Cache Results") = False
Set objRecordSet = objCmd.Execute
If objRecordset.Recordcount = 0 then ' If no user is found then the recordcount will be 0
msgbox "No user is logged on"
Resultstring = ""
Set objCmd = Nothing
Set objRootDSE = Nothing
Set objRecordSet = Nothing
Set objWMI = Nothing
Set Items = Nothing
exit sub
End if
Set objRecordSet = objCmd.Execute
objRecordSet.MoveFirst
Resultstring = Resultstring & vbcrlf & "Name: " & objRecordset.fields("DisplayName")
Msgbox Resultstring
Resultstring = ""
Set objCmd = Nothing
Set objRootDSE = Nothing
Set objRecordSet = Nothing
Set objWMI = Nothing
Set Items = Nothing
End Sub

Need a VB Script to check if service exist

I want to write a VBS script which will check if specific service is installed/exist or not locally.
If it is not installed/exist, script will display message (any text) and disabled the network interface i.e. NIC.
If service exist and running, NO Action. Just exit.
If service exist but not running, same action, script will display message (any text) and disabled the network interface i.e. NIC.
i have below given code which is displaying a message in case one service is stop but it is not -
Checking if service exist or not
Disabling the NIC
strComputer = "."
Set objWMIService = Getobject("winmgmts:"_
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = onjWMIService.ExecQuery _
("select State from Win32_Service where Name = 'dhcp'")
For Each objService in colRunningServices
If objService.State <> "Running" Then
errReturn = msgbox ("Stopped")
End If
Next
Please help. Thanks in advance.
To know if service is installed, check colRunningServices.Count . It will be 0 if no service match the wmi query.
To disable NIC, use a wmi query SELECT * FROM Win32_NetworkAdapter, iterate de returned collection of NICs, find the one you are interested and use the Disable/Enable method of it. BUT this only will work if OS is Vista or later.
It would look something like this but I cannot test this!
Option Explicit
Const TITLE = "Title"
Const SERVICE = "dhcp"
Dim wmi
Dim svcs,svc
Set wmi = GetObject("winmgmts:\\.\root\cimv2")
Set svcs = wmi.ExecQuery("Select * from Win32_Service where Name = '" & SERVICE & "'")
If svcs.Count = 0 Then
Call MsgBox(SERVICE & " service does not exist",vbCritical,TITLE)
Call disableNIC(wmi)
Else
For Each svc In svcs
If svc.State <> "Running" Then
Call MsgBox(SERVICE & " service is not running",vbCritical,TITLE)
Call disableNIC(wmi)
End If
Next
End If
Set wmi = Nothing
WScript.Quit
Sub disableNIC(ByRef wmi)
Dim nics,nic
Set nics = wmi.ExecQuery("Select * from Win32_NetworkAdapter")
For Each nic In nics
nic.Disable
Next
End Sub
Beware that this disables every NIC. If you want to specify one you'd have to add a where clause in disableNIC. Also I imagine you would have to run this as an administrator.
Seems like a weird thing to want to do though...

Start Service with VBscript

I am trying to have this script take a text file running and stopped services before a reboot and start any services that did not automatically start after the machine starts back up. The script that gets the list of service names, state and startmode and creates a comma separated text file line by line works fine. Here it is for reference (taken from the interwebs, lost the link in my travels. Modified slightly.):
Const ForAppending = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile("service_list.txt", _
ForWriting, True)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service")
For Each objService in colListOfServices
objLogFile.Write objService.Name & ","
objLogFile.Write objService.StartMode & ","
objLogFile.Write objService.State
objLogFile.Writeline
Next
objLogFile.Close
This next bit reads the file line by line, compares the state of all of the services with the state of the services that were recorded before the machine was shut down. If they match, do nothing, if they are different, start the service:
Const ForReading = 1
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objServiceName = objWMIService.get("Win32_Service.Name='" & ServiceName & "'")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("\\some path\service_list.txt",ForReading,True,-2)
Do Until objFile.AtEndOfStream
fLine = Split(objFile.ReadLine,",")
'wscript.echo fLine(2)
if InStr(fLine(2),"Running") then
'wscript.echo "it was running!"
if objServiceName.Started then
'do nothing
else
'Set servicetostart = objWMIService.ExecQuery ("Select " & ServiceName & " from Win32_Service Where Name ='Alerter'")
'servicetostart.StartService()
'Result = objServiceName.StartService
'If 0 <> Result Then
' wscript.echo "Start " & ServiceName & " error:" & Result
'End If
objServiceName.StartService
'wscript.echo Servicename & "could not start with error: " & Result
end if
end if
'wscript.echo objServiceName
Loop
As of right now I am recieving an error whenever it actually tries to start the service. I receive a "Provider Failure code:80041004 Source:SWbemObjectEX". I have been looking through the posts about this error and attempting the fixes suggested. Also, as you can see, I have been trying variations, but I am afraid I am merely guessing.
So to my question, what is causing the "Provider Failure"? I have looked up these information for the Win32_Service Class here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394418%28v=vs.85%29.aspx#methods
and looked up the method here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa393660%28v=vs.85%29.aspx
But have been unable to work out where the I am going wrong.
Thanks,
Joe
on a side note, the service I am testing, ie. making sure the service is starting, creating the text file, then stopping the service and running the "start service" code is Windows Defender. The service name is "WinDefend".
FINAL WORKING CODE:
Const ForReading = 1
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("\\vmware-host\Shared Folders\Documents\Biffduncan\Monthly Server Maintanence\service_list.txt",ForReading,True,-2)
Do Until objFile.AtEndOfStream
fLine = Split(objFile.ReadLine,",")
Set objService = objWMIService.get("Win32_Service.Name='" & fLine(0) & "'")
if InStr(fLine(2),"Running") then
'wscript.echo "it was running!"
if objService.Started then
'do nothing
else
Result = objService.StartService()
if Result <> 0 then
wscript.echo "The service: " & objService.Name & " did not start with error: " & Result
else
wscript.echo "Service " & objService.Name & " started"
end if
end if
end if
Loop
Error code 0x80041004 means that the WMI provider encountered an error after it was already initialized. The error code doesn't say anything about the cause of the error, though, nor does it provide any details. Try running WBEMTest or WMIDiag to track down the error. Also check the eventlog for related errors/warnings. If everything else fails, try rebuilding the WMI repository.
As for your code, the first thing I'd do is strip it down to the bare minimum, to avoid potential error sources:
Set wmi = GetObject("winmgmts://./root/cimv2")
Set svc = wmi.Get("Win32_Service.Name='WinDefend'")
rc = svc.StartService
WScript.Echo rc
Also, I wouldn't recommend writing the service status to a file at some random point in time, and then try starting services according to the contents of that file. There is no guarantee that the start mode hasn't been changed since the file was created, or that the service is even installed anymore.
Whether or not a service should be started is indicated by its StartMode property, so just check those services that are set to Auto. Services set to Manual will be started by the system on demand, so there's no need to launch them just because they were running when you took the snapshot.
qry = "SELECT * FROM Win32_Service WHERE StartMode='Auto'"
For Each svc In wmi.ExecQuery(qry)
If Not svc.Started Then svc.StartService
Next

How to run an exe by client remotely on server using vb6

I'm using code below to execute my commands in cmd. Which is actually made for running an exe on my server.
Private Sub Command1_Click()
Dim FN As Integer
FN = FreeFile
'DOS COMMANDS
ServerName = "\\mydbserv"
ExePath = """d:\myfolder\my.exe"""
UserName = "myserver\myuser"
Password = "mypass"
MyCommand = "psexec " & ServerName & " -u " & UserName & " -p " & Password & " -i " & ExePath
'Open Bat file
Open "C:\Mybatc.bat" For Output As #FN
Print #FN, "cd c:\Users\myuser"
Print #FN, MyCommand
Print #FN, "Exit"
Close #FN
'Activate
result = Shell("C:\Mybatc.bat", vbHide)
End
End Sub
everything was fine until i seen that cmd is not getting closed when process is done.
and the worse is the exe i was trying to run remotely also not stops. When i check the cpu usage it always shows "00" doesnt even starts.. It shows like working for ever but never works actually.
So my question is :
Why i cant run this exe file remotely? (or why it just shows like running)
How can i remotely run and close when finished this exe file on server?
How can i close the window and process when finished on my pc as well?
How about this?
install Windbg on the server.
config the windbg auto attach to your exe, when your exe is ready to running.
http://ask.brothersoft.com/image-file-execution-options-debugger-83827.html
running your script
after your exe is started, the windbg will attach to it.
input 'g' in the windbg command, let your exe to running.
wait until you think it should finished
ctrl-break to let the process hang on
input '~*kb' to windbg command, to see what's going on in every thread,
to find out why they are waiting, and what they are waiting for?
PSExec will only initiate the start of the process in a computer (most of the time remote), after that it has no control on the exe that is being executed. Kindly try to run it as a process (within a ProcessInfo as in C#)(with shell execute false). Also something like the following can be used to confirm the state of the process in remote PC:
Option Explicit
Private Sub Form_Load()
Dim strComputer As String
Dim sReturn As String
Dim strNameOfUser As Variant
Dim colProcesses As Object
Dim objProcess As Object
strComputer = "." '"." local or "\\ComputerName"
Set colProcesses = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery("Select * from Win32_Process")
For Each objProcess In colProcesses
sReturn = objProcess.GetOwner(strNameOfUser)
If sReturn <> 0 Then
MsgBox "Could not get owner info for process " & objProcess.Name & vbNewLine & "Error = " & sReturn
Else
MsgBox "Process " & objProcess.Name & " is owned by " & "\" & strNameOfUser & "."
End If
Next
End Sub
link : http://www.vbforums.com/showthread.php?355203-RESOLVED-How-to-get-process-information
hope it helps

Resources