Running PSExec to restart services in the SharePoint farm

I´ve been working on an “installer” for SharePoint packages that is supposed to:

  1. Restart the IISADMIN service on all servers in the farm
  2. Install/Re-Intstall the WSPs
  3. Restart the SPTIMER service on all servers in the farm
  4. Activate/Re-Activate some features (based on a config file)

I had first been playing around with PSExec from sysinternals (hence the, perhaps misleading, title of this post) to do the work for me. I had almost gotten it to work as I needed it to but I had some issues with getting it to run across the wire and return an exit code for me.
It either somehow “froze” up on me or didn´t do what I wanted.

After some digging (through the web) I stumbled upon some great posts about the ServiceController class. This little beauty lets you start and stop a service on a given machine which is really all I wanted to do. Maybe PSExec is better if I wanted to some more advanced stuff but that was not the case here.

Here is what I ended up doing (as part of step 1 and 3 in my little installer):

 public static int RestartService(string service, string server)
 {
 string DomainAndServer = string.Format("{0}.{1}", server, IPGlobalProperties.GetIPGlobalProperties().DomainName);

 ServiceController svc = new ServiceController
 {
   ServiceName = service,
   MachineName = DomainAndServer
 };

 try
 {
   Logger.Current.WriteLine("Running restart of service '{0}' on '{1}'",
                service, DomainAndServer);

   StopService(svc);
   StartService(svc);
   return 0;
 }
 catch
 {
   return 1;
 }

 }

You might notice that I´m using IPGlobalProperties to get the fully qualified name of the server (noticed that I needed that since SP writes a couple of entries in the hosts file that shrews up the server names otherwise).
Note: There is an overload for this one also that runs on the local machine

Here are the Start and Stop methods:

static int StopService(ServiceController service)
{
if (service.Status == ServiceControllerStatus.Stopped)
{
return 0;
}

try
{
Console.WriteLine("Stopping service...");
service.Stop();

service.WaitForStatus(ServiceControllerStatus.Stopped);
return 0;
}
catch (Exception e)
{
Logger.Current.WriteLine("An exception occured while stopping service {0}, details {1}",
service, e);

return 1;
}

}

static int StartService(ServiceController service)
{
if (service.Status == ServiceControllerStatus.Running)
{
return 0;
}

try
{
Console.WriteLine("Starting service...");
service.Start();

service.WaitForStatus(ServiceControllerStatus.Running);
return 0;
}
catch (Exception e)
{
Logger.Current.WriteLine("An exception occured while starting service {0}, details {1}",
service, e);

return 1;
}
}

And finally here is how you would call it:

foreach (SPServer server in servers)
{
  if (server.IsLocalServer())
  {
    Logger.Current.WriteLine("Running on local server");
    result = ServiceUtil.RestartService("IISADMIN");
  }
  else
  {
    Logger.Current.WriteLine("Running on remote server");
    result = ServiceUtil.RestartService("IISADMIN", server.Name);
  }
}
...

That little extension method there, IsLocalServer, looks like this:

public static bool IsLocalServer(this SPServer instance)
{
if (instance.Name.ToLowerInvariant() == Environment.MachineName.ToLowerInvariant())
{
return true;
}

return false;
}
IPGlobalProperties
Advertisements

, ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: