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

Tuesday, November 27, 2012

Run exe using NetworkService account

Sometime back we had a requirement of running an exe in the context of network user. Initially it looked very easy. But when I tried to impersonate the execution, I realized the difficulty. It is easy to impersonate as a standard user .But cannot impersonate as NetworkService. So what are the alternatives.

  1. Run a windows service and start the process/executable from that service.
  2. Schedule a task and specify target as our exe and use NetworkService to initiate execution. Delete the task after execution.

Run exe through windows service

This is a simple matter or creating a windows service and executing a exe when we start the service. Immediately after completion of exe stop the service.This can be summarized as

  1. Create a simple windows service
    1. This should accept an exe path through the OnStart() method.
    2. Execute the exe.
    3. Stop the service by calling Stop() method.
  2. Use the sc start command to start the service and pass path as param.

You may download the program from here.

Schedule task on behalf of NetworkService

This too simple. The steps are

  1. Create a scheduled task pointing to your application using ‘schtasks’ command.
    1. Use “NT AUTHORITY\NETWORK SERVICE" as user profile
    2. Give the run frequency as onlogon. This is to ensure that, it will never run before we trigger.
    3. eg: <drive>:\<folder>>schtasks /create /tn testser /sc onlogon /ru "NT AUTHORITY\NETWORK SERVICE" /tr d:\Temp\HelloWorld.exe (No way to reduce params)
  2. Run the task
    1. schtasks /run /tn "testser"
  3. Delete the task
    1. schtasks /delete /tn testser /f (/f is to delete forcefully.Else it will ask a confirmation)

Better wrap this into a single batch file which accepts the exe name and run the same in the context of ‘NetworkService’. ie you can use like RunAsNetworkService <file path>

NB: If you simply create the task using command, it will not run, it is in a portable system such as laptop and it is in battery during invocation. To resolve that, you need to create an xml file where you can specify to enable task running in batteries and point the same xml in the task creation command.Below links explains how to create task with xml file option.

http://stackoverflow.com/questions/9075564/change-settings-for-power-for-windows-scheduled-task
http://msdn.microsoft.com/en-us/library/windows/desktop/bb736357(v=vs.85).aspx

Monday, June 18, 2012

Getting service account of windows service from C#.Net

Again another scenario from the tool which I had to work couple of weeks back. One of installers in the release pack had a windows service installer and that windows service had to be in a particular windows service account other than NetworkService. This obviously came to the tool’s requirement basket.
When we think about the windows service management the first class which will come into mind is the ServiceController. This can be easily initialized using its constructor by passing the service name and we can play around it. But unfortunately this don’t have details about the service account on which the windows service is running . (You can get the service name easily, if you go to the log on tab in service properties). So what to do? Yes our famous WMI apis are there to help.Simply get the object of our service and get the “StartName” property.
private bool CheckWindoesServiceAccount(string serviceName,string serviceAccountName)
{
    //ServiceController sc = new ServiceController("SSBExternalActivator");
    ManagementObjectSearcher theSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Service where Name='" + serviceName + "'");
    ManagementObjectCollection CollectionOfResults = theSearcher.Get();
    foreach (ManagementObject CurrentObject in CollectionOfResults)
    {
        Console.WriteLine(CurrentObject.Properties["StartName"].Name + " : " + CurrentObject.Properties["StartName"].Value);
        if (!CurrentObject.Properties["StartName"].Value.ToString().Contains(serviceAccountName)) return false;
        return true;
    }
    return false;
}






Happy coding.