...A place where sharing IT monitoring knowledges

Showing posts with label Windows. Show all posts
Showing posts with label Windows. Show all posts

Saturday, 2 February 2013

Restarting Windows services from Linux


The post Monitoring Windows services covered how to remotely check a service status (running, stopped) using WMI, a powerful framework for fetching info from Windows based systems.

All of us managing monitoring systems know how important is providing proactive capabilities to the system in order to fix simple problems as a first step once an incidence is detected. Maybe the best example might be an stopped Windows service: It might be desirable that the monitoring system tried to restart it and, once a given number of unsuccessful tries were made, it performed a notification to the administrators in order to manage the problem in a more human-like way.

Sadly WMI is not so useful when trying to being interactive with the remote system. If not using sql-like syntax, it's is possible calling a local script when a given condition is true (for instance when a service is stopped) but the Linux wmi client (wmic) only support sql-like queries. Moreover, even if sql queries supported running commands under certain circumstances, a remote script might exist on the Windows server side in order to be run (whose existence migth be a problem when dealing with strict remote server administrators).

Let's dance

SAMBA is the Linux implementation of the Windows SMB protocol that allows, among others, supporting Remote Procedure Call transport (RPC over SMB)... and obviously RPC allow us remotely calling Windows procedures, what seems a good solution for our purpose.

samba-client is a package available for different platforms (it is called smbclient in Debian-like plataforms) that groups different utilities for interacting from Linux hosts with remote SMB compatible systems (as Windows servers). One of these utilities is net, that is meant to work just like the net utility available for Windows and DOS.

On a Windows system, we can restart an stopped service calling net in this way:

net start my_windows_service

Using the samba net utility, we can do the same action from a remote Linux system in this way:

net rpc service start my_windows_service \
-I 192.168.0.64 \
-U myDomain/jdoe%jdoe_password

The only difference is that, while in Windows you can use both long (quoting it) or short service name, in Linux you can use just the short service name.

The previous command started a service called my_windows_service on a remote Windows server with address 192.168.0.64 using the privileges of the user jdoe (authenticated with password jdoe_password) belonging to the Active Directory domain myDomain. It is possible doing it using a local user if the domain name (and the slash) is omitted:

net rpc service start my_windows_service \
-I 192.168.0.64 \
-U jdoe%jdoe_password

Finally, using net is possible checking if a given service is running, something useful for validating that a restarted service operation succeeds:

net rpc service status my_windows_service \
-I 192.168.0.64 \
-U myDomain/jdoe%jdoe_password

In practice

Let's assume we are managing a Nagios Core based system that monitors the status of some services running on remote Windows servers. The way to do it was covered in the post Monitoring Windows services.

Now we want to give our monitoring system proactive capabilities in this way: Once a monitored windows service is detected as stopped, our monitoring system must restart it for a given number of tries and, if not achieved, stop doing it and notifying the incidence to the defined contacts (or contactgroup members).

That can be achieved by defining an event handler bound to the service check. Since an event handler executes a command every time a service or host is in a soft state and the first time it goes to a hard (OK or non-OK) state, we will create a command that restarts the Windows service if the Nagios service check is in a non-OK, soft state. Since we can define how many checks can be run before going to a hard state via the service property max_check_attempts, we can set how many service restart tries can be performed before going to a hard state and then running a notification. Let's see it step by step:

1.- Create an script for restarting a windows service if a nagios service is in a soft, non-ok state. Name it 'restart_win-service' and save it in the Nagios libexec directory (with the right permissions for being executed from Nagios):

#!/bin/sh
#
# restart_win-service
# Restarts a remote windows service if nagios service is 
# in a non ok, soft state
# Arguments:  sevice_status service_status_type user_id 
#             server_address service_name  
#


if [ "$1" != 'OK' -a "$2" == 'SOFT' ]; then
# We are in a soft, non OK status: 
# Restart the service
net rpc service start $5 -I $4 -U $3 > /dev/null 2> /dev/null
fi


2.- Define a Nagios command representing the previous script:


define command{
command_name restart_win_service
command_line $USER1$/restart_win-service $SERVICESTATE$ $SERVICESTATETYPE$ $ARG1$ $HOSTADDRESS$ $ARG2$
}


3.- Configure the service for using the command restart_win_service as event handler and running it for three times before notifying the problem

define service {
...
enable_event_handler 1
event_handler restart_win_service!myDomain/jdoe%jdoe_password!my_windows_service
max_check_attempts 3
...
}




Thursday, 6 December 2012

Monitoring Windows services with WMI


One of the most important tasks when monitoring Windows servers is controlling the status of critical services. In this post I'll explain how to externally check if they are running using WMI.

The key point for using WMI instead other until now common methods (NSClient++) is clear: WMI is Windows native and it doesn't require third-party software installation on the server side, what leverages you of:

  • agent software periodic upgrades
  • potential security holes
  • (what translates to) long and boring server administrators discussions
This post must not be considered as an in-depth WMI howto but as a "if you need to do it follow this way". You can find tons of info on the Web deeply covering each aspect of configuring a Windows system for allowing WMI remote access.

WMI

Windows Management instrumentation is the infrastructure for management data and operations on Windows-based operating systems, what can be translated to all you need to know about a Win XP, Vista, Windows 7, Windows 8, 2003 server and 2008 server can be retrieved via WMI.

wmic is a Windows command-line program that allows you interacting with WMI from both a local or a remote windows-based system. For instance, it allows us checking what are the running processes calling wmic from the command line in this way:

>wmic SERVICE where (state=”running”) GET caption, name, state

WMI on the linux side

Luckily for us it exists wmi-client, a Linux program that allows us getting the same kind of info but, in this case, running sql-like queries from a remote Linux host:

>wmic -U myDomain/jdoe%jdoe_password //192.168.0.64 "select caption, name, state from Win32_Service where state='running'"

The previous command will retrieve the name, caption and state from all running services in a windows host with address 192.168.0.64 using the credentials of the user jdoe (password jdoe_password) that belongs to a Windows domain called myDomain.

wmi-client 1.3.14 packages for Debian (Squeeze) and Ubuntu (Maverick) are available in the Mike Palmer's website (sorry Mike, I've no available online resources for storing them). For those not using Debian-like systems, the wmi-client 1.3.13 source package is available on the Zenoss repository.

Granting remote access to WMI

Once wmi-client is installed on your Linux system, the only needed for starting to play with is:
  • Configuring the remote Windows system for supporting external WMI queries.
  • Defining a user with enough privileges for running remote WMI queries.
About the first task, if you're dealing with Windows 2003/2008 servers you don't need to do anything on the server side since WMI access is enabled from scratch. 

About defining a user, you can google for finding many literature (and the most wrong) about how to configure it with just the needed privileges for running WMI queries, but if you need to go for it faster just create a local user with admin privileges. Moreover, if you need to go for it fastest, create that user in the domain and prefix the user name with the domain name in the way domain/user (like in the previous example).

Monitoring services

Once you get remote server access, it's time to allow your monitoring system managing the available info retrieved via WMI. For that purpose you need to run a query that returns the status of a service given its name, for instance "select state from Win32_Service where name='target_service_name'".

In order to feed your monitoring system with the retrieved info you can proceed in different ways:
  • Calling wmic command and parsing its output.
  • If you like Perl, you can manage the previous query using Net::WMIClient, an programatic interface for wmic binary.
Nagios-core compatible solutions users (what include Nagios, Centreon, Icinga, OP5) can rely on check_wmic_plus, a well documented mega-plugin that allows getting, among many others, info related to service status running on a remote WMI system:

define command{
command_name check_wmi_service
command_line $USER1$/check_wmi_plus.pl -H $HOSTADDRESS$ -u $ARG1$ -p $ARG2$ -m checkservice -a '$ARG3$' --inidir=/usr/local/nagios/libexec -c _NumBad=0
}

In the previous example a command named check_wmi_service is defined for monitoring if a given service is running. It is based on these variables:
  • $HOSTADDRESS$: The address of the WMI compatible Windows seerver
  • $ARG1$: The user name (if you're using a local user) or the domain/username (if you are using a domain user)
  • $ARG2$: The user password
  • $ARG3$: A regular expression matching the service name
That command will return OK if one or more services whose name matches $ARG3$ regex are running, else it will return CRITICAL since the threshold for services in "bad" state is set to 0 (-c _Numbad=0).

So, for instance, you can define a service using the previous command for checking if the MS Enchange address book service (called MSExchangeAB) is running if in this way:

define service{
host_name ExchangeServer
service_description Address book service
check_command check_wmi_service!jdoe!jdoe_password!^MSExchangeAB$
...
}


 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes