Download ActiveXperts SMS Messaging Server 5.0  (7590 KB - .exe file)
Case studies - How SMS Messaging Server is used by existing customers
Case Study: SMS commands to remote reboot Windows servers and remote restart Windows services
1. Background
2. Problem Statement
3. Goals of the new System
4. ActiveXperts SMS Messaging Server Solution
1. Background
SupportIT is an IT consultancy company supplying small and medium sized businesses with networking solutions and IT computer support.
From Firewall and VPN installations to Microsoft upgrades and migrations, to a complete network audit and support service,
SupportIT has the experience and expertise.
Qualified and experienced Microsoft engineers are doing consultancy work.
From storing Microsoft data from a failed server to upgrading and migrating Exchange servers to the latest versions.
This case study describes how SupportIT implemented an SMS-based solution to reboot servers and restart services from remote locations.
A working demo of this case study is included with the ActiveXperts SMS Messaging Server installation.
2. Problem Statement
The SupportIT staff members need a facility to reboot Windows computers or restart Windows services at any time,
even when they are at a location where there is no network available.
Now, they need to make a phone call to a collegue and ask the person to reboot a machine or reboot a service. They want to be able to do this automatically via SMS.
3. Goals of the new System
Goals of the new system:
- Ability to reboot a server using SMS
- Ability to shutdown a server using SMS
- Ability to query a service on a server using SMS
- Ability to stop a service on a server using SMS
- Ability to start a service on a server using SMS
- The system should only allow SMS commands from mobile numbers of the support staff of the company.
4. ActiveXperts SMS Messaging Server Solution
SupportIT uses a dedicated server for running ActiveXperts SMS Messaging Server. This system receives incoming SMS commands,
checks the command for its syntax, checks if the command was sent by an SupportIT helpdesk member, and executes the reboot/restart command.
In case a users sends a command that doesn't meet the syntax requirement, a 'how to use' message is returned.
SMS message format
The system handles SMS messages as follows:
|
|
|
SMS syntax
|
Sample
|
Explanation
|
|
REBOOT <server>
|
REBOOT fileserver03
|
Reboot a server or workstation
|
|
SHUTDOWN <server>
|
SHUTDOWN fileserver03
|
Shutdown a server or workstation
|
|
QUERYSVC <server> <service>
|
QUERY webserver02 w3svc
|
Query the state of a service on a particular server/workstation
|
|
STOPSVC <server> <service>
|
STOPSVC webserver02 w3svc
|
Stop a service on a particular server/workstation
|
|
STARTSVC <server> <service>
|
STARTSVC webserver02 w3svc
|
Start a service on a particular server/workstation
|
|
<any other message>
|
Please help
|
Unrecognized command. A Help message is replied
|
|
Hardware and Software
The system consists of the following:
- A Windows server - Dell PowerEdge with 2GB of RAM, 250 GB SATA 7200 rpm Hard Drive, Intel Core2Duo processor, running Windows 2003 Server
- The systems runs ActiveXperts SMS Messaging Server 5.0
- Falcom SAMBA 75 GSM/GPRS modem - to handle all incoming/outgoing request and replies.
A GSM/GPRS modem throughput (10 messages per minute) is sufficient for this solution.
They selected a Falcom SAMBA 75 GSM/GPRS modem, together with a SIM card (including an SMS bundle of 5000 SMS messages).
This SIM card is inserted into the Falcom SAMBA GSM/GPRS modem.
The SIM card is associated with the following GSM number: +3565099212.
Trigger
A Trigger is called when a new messages arrives in the system.
SupportIT handles only one type of SMS messages: incoming reboot/restart commands. Therefore, only one trigger is required:
.
|
|
|
Enabled
|
Description
|
Condition
|
Script
|
|
YES
|
Process incoming commands
|
To = '+3565099212'
|
\Projects\SupportIT\Triggers\SupportIT.vbs
|
|
The trigger function is always called 'ProcessMessage' (mandatory name) and is always called by the SMS Messaging Server service with one parameter: the message ID of the message to be processed.
The 'ProcessMessage' function in the 'SupportIT.vbs' file handles the following:
- Set incoming message to 'processed', so it will not be processed again by the system
- If syntax not matched => send an SMS reply to the sender
- Reboot/Shutdown command => Verify paramters; there should be one
parameter: the computername
- Query/Stop/Start service command => Verify paramters; there should be two
parameters: computername and servicename
- Execute command
SupportIT.vbs (full code)
' // ========================================================================
' // SupportIT.vbs
' // ------------------------------------------------------------------------
' //
' // REBOOT server01
' // SHUTDOWN server01
' // QUERYSVC server01 messenger
' // STARTSVC server01 messenger
' // STOPSVC server01 messenger
' // ========================================================================
Option Explicit
CONST STR_DEBUGFILE = "\Sys\Tmp\Sample Project - SupportIT.txt"
Const STR_USAGE = "Usage: REBOOT/SHUTDOWN server | QUERYSVC/STOPSVC/STARTSVC server service"
Const CMD_UNKNOWN = 0
Const CMD_REBOOT = 1
Const CMD_SHUTDOWN = 2
Const CMD_QUERYSVC = 3
Const CMD_STARTSVC = 4
Const CMD_STOPSVC = 5
' Declaration of global objects
Dim g_objMessageDB, g_objDebugger, g_objConstants
' Creation of global objects
Set g_objConstants = CreateObject( "AxMmServer.Constants" )
Set g_objMessageDB = CreateObject( "AxMmServer.MessageDB" )
Set g_objDebugger = CreateObject( "ActiveXperts.VbDebugger" )
' Set Debug file - for troubleshooting purposes
g_objDebugger.DebugFile = STR_DEBUGFILE
g_objDebugger.Enabled = False
' // ========================================================================
' // Function: ProcessMessage
' // ------------------------------------------------------------------------
' // ProcessMessage trigger function to process incoming messages
' // ========================================================================
Function ProcessMessage( numMessageID )
Dim objMessageIn
Dim numCommand, strServer, strService, strReplyMessage
Dim bResult
g_objDebugger.WriteLine ">> ProcessMessage"
' Open the Message Database
g_objMessageDB.Open
If( g_objMessageDB.LastError <> 0 ) Then
g_objDebugger.WriteLine "<< ProcessMessage, unable to open database"
Exit Function
End If
' Retrieve the message that has just been received. If it fails then exit script
Set objMessageIn = g_objMessageDB.FindFirstMessage( "ID = " & numMessageID )
If g_objMessageDB.LastError <> 0 Then
g_objMessageDB.Close
g_objDebugger.WriteLine "<< ProcessMessage, FindFirstMessage failed: g_objMessageDB.LastError
Exit Function
End If
' Change Status to from Pending to Success.
objMessageIn.Status = g_objConstants.MESSAGESTATUS_SUCCESS
g_objMessageDB.Save objMessageIn
g_objDebugger.WriteLine "Incoming message saved, result: [" & g_objMessageDB.LastError & "]"
' Retrieve Member's name
bResult = GetCommand( objMessageIn.Body, numCommand, strServer, strService, strReplyMessage )
If( bResult ) Then
Select Case numCommand
Case CMD_REBOOT
Win32ShutDown strServer, True, strReplyMessage
Case CMD_SHUTDOWN
Win32ShutDown strServer, False, strReplyMessage
Case CMD_QUERYSVC
CheckServiceState strServer, strService, strReplyMessage
Case CMD_STARTSVC
StartOrStopService strServer, strService, True, strReplyMessage
Case CMD_STOPSVC
StartOrStopService strServer, strService, False, strReplyMessage
Case Else
strReplyMessage = "Unknown."
End Select
End If
ReplyMessage objMessageIn, strReplyMessage
' Close the Message Database
g_objMessageDB.Close
g_objDebugger.WriteLine "<< ProcessMessage"
End Function
' // ========================================================================
' // Function: GetCommand
' // ========================================================================
Function GetCommand( strBody, ByRef numCommand, ByRef strParam1, ByRef strParam2, ByRef strErrorMessage )
Dim arrMessage
GetCommand = False
numCommand = CMD_UNKNOWN
strParam1 = ""
strParam2 = ""
strErrorMessage = ""
arrMessage = Split( UCase( Trim( strBody ) ), " " )
If( UBound( arrMessage ) < 1 ) Then
GetCommand = False
strErrorMessage = "Syntax error. " & STR_USAGE
Exit Function
End If
Select Case UCase( arrMessage(0) )
Case "REBOOT"
numCommand = CMD_REBOOT
Case "SHUTDOWN"
numCommand = CMD_SHUTDOWN
Case "QUERYSVC"
numCommand = CMD_QUERYSVC
Case "STARTSVC"
numCommand = CMD_STARTSVC
Case "STOPSVC"
numCommand = CMD_STOPSVC
Case Else
numCommand = CMD_UNKNOWN
End Select
If( numCommand = CMD_UNKNOWN ) Then
GetCommand = False
strErrorMessage = "Syntax error. " & STR_USAGE
Exit Function
End If
If( ( numCommand = CMD_REBOOT Or numCommand = CMD_SHUTDOWN ) And UBound( arrMessage ) <> 1 ) Then
GetCommand = False
strErrorMessage = "Parameter mismatch. " & STR_USAGE
Exit Function
End If
If( ( numCommand = CMD_QUERYSVC Or numCommand = CMD_STARTSVC Or numCommand = CMD_STOPSVC )
And UBound( arrMessage ) <> 2 ) Then
GetCommand = False
strErrorMessage = "Parameter mismatch. " & STR_USAGE
Exit Function
End If
' Assign strParam1 and optionally strParam2
If( UBound( arrMessage ) >= 1 ) Then
strParam1 = arrMessage( 1 )
End If
If( UBound( arrMessage ) >= 2 ) Then
strParam2 = arrMessage( 2 )
End If
GetCommand = True
End Function
' // ========================================================================
' // ReplyMessage
' // ------------------------------------------------------------------------
' // Auto reply to every incoming SMS message
' // ========================================================================
Function ReplyMessage( objMessageIn, strResponse )
Dim objMessageOut
g_objDebugger.WriteLine ">> ReplyMessage"
' WRITE YOUR CODE HERE (for instance: forward message to an e-mail address, see below)
Set objMessageOut = g_objMessageDB.Create
If( g_objMessageDB.LastError = 0 ) Then
objMessageOut.Direction = g_objConstants.MESSAGEDIRECTION_OUT
objMessageOut.Status = g_objConstants.MESSAGESTATUS_PENDING
objMessageOut.Type = objMessageIn.Type
objMessageOut.To = objMessageIn.From
objMessageOut.ChannelID = 0
objMessageOut.BodyFormat= objMessageIn.BodyFormat
objMessageOut.Body = strResponse
g_objMessageDB.Save objMessageOut
End If
g_objDebugger.WriteLine "<< ReplyMessage"
End Function
'// ==================================================
'// START/STOP A SERVICE AND ITS DEPENDENTS
'// ==================================================
Function StartOrStopService(strComputer, strService, bStart, ByRef strMessage )
On Error Resume Next
strMessage = "Unknown result."
StartOrStopService = False
'// CONNECT TO WMI ON DESTINATION COMPUTER
Dim objWMIService
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If(Err.Number <> 0) Then
StartOrStopService = False
strMessage = "Unable to connect to WMI service on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// GET SERVICE COLLECTION FOR THIS SERVICE
Dim colServiceList
Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
If( colServiceList.Count = 0 ) Then
StartOrStopService = False
strMessage = "Unable to find service '" & strService & "' on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// START or STOP SERVICE
Dim objService, errReturn
For Each objService in colServiceList
If( Err.Number <> 0 ) Then
StartOrStopService = False
strMessage = "Unable to find service '" & strService & "' on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
If( bStart ) Then
objService.StartService()
strMessage = "StartService successfully initiated."
Else
objService.StopService()
strMessage = "StopService successfully initiated."
End If
Next
CheckServiceState = True
'// CLOSE OBJECTS
Set colServiceList = Nothing
Set objWMIService = Nothing
End Function
'// ==================================================
'// CHECK SERVICE STATUS
'// ==================================================
Function CheckServiceState(strComputer, strService, ByRef strMessage )
On Error Resume Next
strMessage = "Unknown result."
CheckServiceState = False
'// CONNECT TO WMI ON DESTINATION COMPUTER
Dim objWMIService
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If(Err.Number <> 0) Then
CheckServiceState = False
strMessage = "Failed to connect to WMI service on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// GET SERVICE COLLECTION FOR THIS SERVICE
Dim colServiceList
Set colServiceList = objWMIService.ExecQuery ("Select * from Win32_Service where Name='" & strService & "'")
If(colServiceList.Count = 0) Then
CheckServiceState = False
strMessage = "Failed to find service '" & strService & "' on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// GET SERVICE STATE
Dim objService
For Each objService in colServiceList
If(Err.Number <> 0) Then
CheckServiceState = False
strMessage = "Failed to find service '" & strService & "' on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
strMessage = "State of service '" & strService & "' on computer '" & strComputer & ": " & objService.State
Next
CheckServiceState = True
'// CLOSE OBJECTS
Set colServiceList = Nothing
Set objWMIService = Nothing
End Function
'// ==================================================
'// MANAGE SERVER (WIN32SHUTDOWN)
'// ==================================================
Function Win32ShutDown( strComputer, bReboot, ByRef strMessage )
On Error Resume Next
Win32ShutDown = False
strMessage = "Unknown result."
'// CONNECT TO WMI ON DESTINATION COMPUTER
Dim objWMIService
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If( Err.Number <> 0) Then
Win32ShutDown = False
strMessage = "Failed to connect to WMI service on computer '" & strComputer & "'"
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// GET OPERATING SYSTEM COLLECTION
Dim colOperatingSystems
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
If (colOperatingSystems.Count = 0) Then
Win32ShutDown = False
strMessage = "Failed to query Win32 Operating System on computer '" & strComputer & "'."
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
'// SEND WIN32SHUTDOWN COMMAND
Dim objOperatingSystem
For Each objOperatingSystem in colOperatingSystems
If (Err.Number <> 0) Then
Win32ShutDown = False
strMessage = "Unable to retrieve Operating System Collection on computer '" & strComputer & "'."
g_objDebugger.WriteLine DateTime() & " " & strMsg
Exit Function
End If
If( bReboot ) Then
objOperatingSystem.Win32Shutdown( 6 )
strMessage = "Reboot of computer '" & strComputer & "' successfully initiated."
Else
objOperatingSystem.Win32Shutdown( 5 )
strMessage = "Shutdown of computer '" & strComputer & "' successfully initiated."
End If
Next
Win32ShutDown = True
End Function
|