Like most Windows administrators, I grew up on the NET executable for command-line service management.  I think every article that Microsoft has ever written which requires or suggests command-line management of services recommends the usage of the NET executable.  For those that may not be aware, or familiar, I want to introduce you to the SC executable and provide a comparison to the NET executable.

For the most part, everything that NET does, SC can do.  The subtle differences are in how they perform the same functions.  Here’s what NET command can do and the corresponding SC command:

NET START

This command really has two functions.  One which is well-known and one that is not.
1.  NET START <servicename> will start a stopped service.

2.  NET START with no service name will list all services running on the machine.

NET START will not resume a paused service.

SC START

and

SC QUERY[EX]

NET STOP

NET STOP will stop a running or a paused service.

SC STOP

NET PAUSE

NET PAUSE will pause a running service.

SC PAUSE

NET CONTINUE

NET CONTINUE will resume a running service.

SC CONTINUE

For each of the NET commands, spaces are not allowed in the <servicename> argument unless the display name is enclosed with quotes.  You can pass the service name of the service as well.  Strangely, SC will only take the short name and will not accept names in quotes.

Here’s where the difference begin.  Though I am not going to list every argument of the SC executable, I do want to highlight some of the interesting ones.

The first, and most consequential, difference is that SC can remotely manage services.  For any SC command, simply type the workstation name or IP address of the machine that you would like to manage right after SC and before the command:

SC SERVERNAME QUERY

SC START

SC START and NET START perform the same basic function when starting a service with one very notable, very important difference.  SC sends the control to the service and then returns to the command prompt.  This typically results in SC START returning the service in a state of START_PENDING.  NET START will wait for the service it is starting to come to a fully started state before it returns control at the command prompt.  We’ll discuss more of why this is important when we talk about this with NET STOP.  SC START does not enumerate running services on the machine.  For that we need to use SC QUERY.

SC QUERY[EX]

The function of SC QUERY and NET START are very similar; they each query and list any started services – running or paused.  However, the differences from there are great.  Where NET START will show the display name for the service only, SC QUERY is going to show the display name, service name (short name), whether the service runs in its own process or a shared process, the state of the service (running or paused), the accepted controls to send the service (eg can the service be paused?), as well as some other data.  Additionally, you can choose to query a single service by passing the service name as an argument of SC QUERY.  This way you don’t have to see the service info for all of the services (which is more than the command buffer can handle by default).  Then there is SC QUERYEX which on top of the standard info also provides extended service information including the very valuable process ID (PID). and system flags.

SC STOP

SC STOP and NET STOP each stop the specified service.  However, like SC START, SC STOP does not wait for the service to come to a stop and will there for often return STOP_PENDING for many service stop operations.  NET STOP on the other hand will wait on the service to stop before it returns to the command prompt.  Now, why does this really matter?  It seems like it would be nice to not have to worry about waiting on slow services to stop before I can keep working.  Well, sometimes that’s true.  Here’s where it may not be.

Success Conditions

Suppose that you want to concatenate commands together either at the command-line or through a script.  For those that don’t know, concatenation is the process of joining two commands together in operation.  I want to have my domain controller re-register all of its SRV records by stopping and starting the NETLOGON service.  At a command prompt I type:

NET STOP NETLOGON & NET START NETLOGON

This will run the NET STOP NETLOGON command and then immediately following, it will execute the NET START NETLOGON.  However, what if the NET STOP doesn’t stop the NETLOGON service?  What if it fails?  Do I want to run the NET START for the service?  To execute the second command only if the first succeeds, I can use conditional concatenation by adding a second ampersand (&).  The above command now becomes:

NET STOP NETLOGON && NET START NETLOGON

Only if the stop was successful will it attempt to start it.  So, if the stop fails because a dependent service won’t stop, or because I don’t answer some on-screen prompt (like do I want to stop the dependent service), then there will be no attempt to perform the second operation.

Alright, that’s interesting but how is that relevant here.  Well, it’s relevant because NET and SC have different ideas of what they consider to be success conditions.  The question SC asks to determine if it was successful is, “Did I successfully send a stop control to the service?”  If it did, regardless of whether the service stopped, then I satisfied the successful condition.  NET asks the question, “Did the service I attempted to stop, return that it stopped successfully?”  If it did, then it satisfied the condition.  If it didn’t, no matter what the reason, then NET fails the successful condition and will not execute the second part.

Because of the different concerns for success, SC doesn’t wait around to find out whether the service stop.  NET does.  So, if I send an SC STOP NETLOGON & SC START NETLOGON, it may fail even though the service will stop normally.  The reason is that SC has already moved on to the second part of the command before the NETLOGON service was able to fully stop.  NET STOP NETLOGON & NET START NETLOGON will only move on after it waits for an answer back from the stop operation.  Furthermore, NET STOP NETLOGON && NET START NETLOGON won’t move on at all if the timeout is reached or if the service does not stop successfully.

For those of you that are interested in command-line scripting or just want to shortcut the waiting, this subtle difference is a big deal.  Using the SC command to restart services for you may very well leave you in a state where services remain stopped.

SC PAUSE

The functionality of SC PAUSE and NET PAUSE are identical.

SC CONTINUE

The functionality of SC CONTINUE and NET CONTINUE are identical.

Here’s a short list of the differences between SC and NET where they perform the same operations:

  • SC QUERY is much more verbose than NET QUERY (SC QUERYEX is even more verbose than SC QUERY)
  • NET accepts service display names in quotes where SC only accepts service names (isn’t that wierd)
  • SC is remotable where NET is not
  • SC considers the sending of the control a successful condition of execution
  • NET considers the service state in determining the successful condition of execution

From here, it’s all in favor of SC.  In future posts we’ll talk about all of the other advanced configuration that can be performed with SC.