This work is licensed under the Creative Commons Attribution-ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA. Originally written by Kynan Dent (http://kynan.org) for TWATech Radio (http://twatech.org). +-= TWAT Intro =---------------------------------------------------------------- | Welcome to TWAT Radio Episode X, where X is a variable between 95 and 100. It's possibly Tuesday the 11th of April and this is another Windows From The Command Line! - Intro Music - Hi, my names's kynan and I'm back with another look at some tools you can use to administer Windows NT-based boxes from the command line. Thanks for the feedback from the last episode, I'll try and keep this one a bit shorter. +- Intro to Services------------------------------------------------------------ Today I'm going to look at a couple of easy ways to manage services from the command line. I guess before we look at the tools we should define what exactly a service is. It's pretty simple because basically a service is just like any other process. The only difference between a normal executable that you can run, like notepad for instance, and a service is the way it is controlled. The special thing about services is that they don't need a user to start them up and they generally don't have a GUI. They're run and managed by a thing called the Service Control Manager or SCM for short. The SCM has a big database of services in the registry and it will start up all of the processes that need to be running in the background for your machine to work. Services can also be manipulated by a users and they are controlled through tools that interface with the SCM. For a lot more information about how services work and how you can code your own check out the MSDN Services entry at http://tinyurl.com/ac9d +- GUI interface to services --------------------------------------------------- Now we know what services are and how they work, how do we actually control them? The standard way is via the Services GUI that you can normally find in the Control Panel. This was a stand-alone applet in NT4 and was upgraded to a snap-in for MMC under Windows 2000 and up. You can start this applet on an NT4 box by running: control.exe %windir%\system32\srvmgr.cpl services On a W2K+ box you can just run: services.msc On a brief tangent, nearly all MMC snap-ins will work on remote servers if you pass them a /computer= flag, the services snap-in is one that will work, provided all the RPC services are running and the're no firewalls in the way. Anyway, either of these commands provides you with a GUI that is basically an interface to the SCM. From here you can start, pause, continue and stop services, mess with the user they run as, change their startup type and setup some recovery actions should the service fail. All well and good but who wants to use a GUI? What are our options from the command line? +- CLI interface to services --------------------------------------------------- There are two basic tools that we can use to administer services from the command line: NET; and SC. We'll start with NET because it's a standard piece of the OS from NT4 right up to Windows 2003. Just before we dig into that there's a tiny little bit of terminology we need to know: I'm going to use the "Windows Installer" service as an example for the rest of this talk because it's pretty ubiquitous and not too tragic if you break it. All services have two names, a Display Name and a Key or Service Name. When I talk about the "Window Installer" service I'm referring to it by it's display name. This is meant to be the human friendly name, kind of like the way domain names hide IPs. The actual service name tends to be a smaller and generally less indicative name. This isn't a hard and fast rule though and often both names are equally mysterious. In the case of the Windows Installer service the service name is MSIServer. Let's look at what we can do with NET. +- NET ------------------------------------------------------------------------- The NET.EXE executable lives in %WINDIR%\SYSTEM32 and is quite a swiss-army-knife. It can do a lot of things that I'm going to talk about in another TWAT (if someone else doesn't get there first), for today we're just going to look at how it can interface with the SCM. There are four options that can be passed to NET to mess with services: NET START NET STOP NET PAUSE NET CONTINUE These sound pretty obvious but there are a couple of hidden features. "NET START" followed by either the service name or the display name will attempt to start up the specified service. If you use the display name then remember to wrap it in double quotes if it contains spaces. If the service is already running then you'll get a message saying so. If not, a message will be passed to the SCM to start up the service and, if it starts succesfully and in a timely fashion you'll get a message saying that the service started. NET will wait for the timeout period to run out before it comes back to you to tell you that the service may not have started. The other thing that "NET START" can do is provide you with a list of currently running services. If you run "NET START" you'll get a list of the display names of all currently running services. NET STOP works in a similar fashion but has no default action to take if you don't give it a service to work on. Those are the most useful tools that NET has for working with servicse. The two other options are PAUSE and CONTINUE. You can probably guess what they do but bear in mind that they only work with services that are explicitly written to have pause functionality, like the TELNET service for instance. If you run NET PAUSE TELNET (assuming that you had the telnet server running) then the service would remain running and it would still accept new connections but it wouldn't provide a logon service and it wouldn't process any more commands from connected users until you ran NET CONTINUE TELNET. If you try to PAUSE a service that hasn't implemented the PAUSE functionality you'll just get an error message saying that PAUSE is not a valid request. And that's NET. Like I said, pretty basic. Let's look at the next step up, SC. +- SC -------------------------------------------------------------------------- What's SC? SC stands for Service Control, or Service Controller, or something of that nature. It provides a much more flexible and powerful way to manage services than NET does. Unfortunately SC is NOT a part of the NT4 default install base and does not actually become standard until Windows 2003. It is a part of the NT4 and Windows 2000 Resource Kits and available for free. You can get version 5.0.2134.1 from the Microsoft Resource Kit FTP site at http://tinyurl.com/s78tk and this will happily run on everything from NT4 up. As I mentioned, SC is much more powerful than NET, essentially it is a command line replacement for the services applet. Not only can we start and stop services but you can change the way they start, disable them and even create or delete them. There's nothing you can do through the GUI that you can't do with SC! SC has some pretty extensive help which you can access by running it without any arguments. The most obvious things you'll want to do are the same things that you can do with NET. Let's cover those first. The SC syntax is pretty simple. SC followed by the command you want to run followed by the service you want to run it on. Unlike NET though, SC will NOT deal with "display names", it will only work if you give it the "service name". Luckily, SC provides a mechanism to obtain "service names" if you already have the "display name" (and vice versa). To get the service name for the "Windows Installer" service for instance, you would run SC GetKeyName "Windows Installer" and you'll be provided with the service name: MSIServer. If you need or want to, you can reverse this and retrieve the display name using the GetDisplayName argument. Once you've got the right name you can stop and start the service just like NET by typing SC start or SC stop If all goes well SC will submit your request to the SCM and return straight away, dumping a pretty verbose report on the current status of the service. This will include, amongst other things, a STATE that will be set to START_PENDING or STOP_PENDING depending on what you've asked SC to do. All that SC does is pass the request to the SCM and exit, it doesn't wait around to see how it all went. You can then use the QUERY argument to query the service and find out if it's stopped or started. There's a beefier version of the query command, queryex that adds the PID and and FLAGS to the query output. The other type of query you can run is QC. QC allows you to check on the actual configuration of the service, things like startup type, dependencies and binary location are some of the fields you'll see reported. Using the QUERY argument you can get a list of running services. Simply run SC QUERY and you'll get a list of all the running services. This is going to be a VERY long list because each service will be listed with the same 8 lines of information that you get from a START or STOP command. The QUERY argument has a few parameters that you can pass it so that you can do more granular searches. For instance, using the STATE field you can retrieve only the services that are stopped (state= inactive) instead of the ones that are running, or even ALL services installed on the box (state= all). Just remember the slightly odd syntax requires that the state= parameter is seperated from the actual state type by a space: +- Screenshot ------------------------------------------------------------------ LOCAL C:\>sc query state= inactive LOCAL C:\>sc query state= all +- End: Screenshot ------------------------------------------------------------- So, we can stop and start services, get names of known services and list services by their status, running, stopped or just present. What more could you want to do to a service? Well, SC doesn't just work WITH services it can work ON them as well. There are three start types for a non-driver service: Auto: Service starts automatically at boot time Demand: Service starts "on demand" or Manually in other words. Disabled: Service WILL NOT START, even if you explicitly request it. Let's say that the Windows Installer service has been disabled "for security purposes". You want to turn it back on so that you can install something. SC has command called CONFIG to do just that. Using QC you can see what the current configuration settings are for a particular service. This gives you all kinds of useful information including the location for the service executable, any dependencies it may have and when it starts up (amongst other things): +- Screenshot ------------------------------------------------------------------ LOCAL C:\>sc qc MSIServer [SC] GetServiceConfig SUCCESS SERVICE_NAME: MSIServer TYPE : 20 WIN32_SHARE_PROCESS START_TYPE : 4 DISABLED ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\WINNT\system32\msiexec.exe /V LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Windows Installer DEPENDENCIES : RpcSs SERVICE_START_NAME : LocalSystem +- End: Screenshot ------------------------------------------------------------- Running SC CONFIG will provide you with enough help to make an informed decision on what you want to do. To change the start type you just need to run SC CONFIG SERVICE_NAME start= START_TYPE: +- Screenshot ------------------------------------------------------------------ LOCAL C:\>sc start msiserver [SC] StartService FAILED 1058: The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. LOCAL C:\>sc config MSIServer start= demand [SC] ChangeServiceConfig SUCCESS LOCAL C:\>sc qc MSIServer [SC] GetServiceConfig SUCCESS SERVICE_NAME: MSIServer TYPE : 20 WIN32_SHARE_PROCESS START_TYPE : 3 DEMAND_START ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\WINNT\system32\msiexec.exe /V LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Windows Installer DEPENDENCIES : RpcSs SERVICE_START_NAME : LocalSystem LOCAL C:\>sc start msiserver SERVICE_NAME: msiserver TYPE : 20 WIN32_SHARE_PROCESS STATE : 2 START_PENDING (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x7d0 PID : 1368 FLAGS : +- End: Screenshot ------------------------------------------------------------- There is a lot more to SC, including the ability to operate on services hosted on remote servers and I highly recommend reading the whole man page (or whatever they're called in MS land). There is documentation included in the zip file that's on the other end of the TinyURL that I mentioned before or you can read the manual for the version of SC included in Windows 2003 at http://tinyurl.com/p6kct There's one more thing I want to mention. I said earlier that you can use SC to CREATE and DELETE services. It's important to remember that although a service is just another process based on just another executable, not just any executable can be a service. The executable has to implement the various methods that the SCM will try to use to start and stop a service normaly. If you've got an executable that wasn't written with the intention of running it as a service then it just won't work. You can try this with notepad for instance. Running: sc create Notepad binPath= notepad.exe will report a success but if you try to start your new Notepad service you'll get an error. This is because the notepad executable doesn't understand what it's being asked to do. You can get around this by using a handy utility called srvany.exe. This is another Resource Kit tool that you can get from http://tinyurl.com/hx8nc srvany.exe is basically a wrapper that will listen for requests from the SCM and pass them on to your application. Using notepad as an example again, you'd change the command line to: sc create Notepad binPath= %WINDIR%\SYSTEM32\srvany.exe Now you need to make a change to the registry to add the parameters. You can do this using the REG command that I talked about in TWAT 82 (by the way, I forgot to mention that you can get REG as part of the SP4 Support Tools, downloadable from the MS website at: http://tinyurl.com/kh9lp). The REG command line would be REG ADD HKLM\System\CurrentControlSet\Services\Notepad\Parameters /v Application /d "C:\WINNT\SYSTEM32\NOTEPAD.EXE" Now you'll be able to start and stop your notepad service! It won't actually do anything visible but if you check the Task Manager you'll see that there's a copy of the notepad application running and it will disappear when you stop the Notepad service. Obviously this isn't very useful but it does demonstrate the concepts. If there's an application that you always need running in the background then this could be a good way to deal with it, the main thing to remember is that the signals that srvany uses are not ones that normal applications expect to see, specifically the shutdown request that it sends when you stop the service is the TerminateProcess API call which will essentially kill the process without letting it clean up first. On that note, it's time to wrap up! This has been another episode of Today With A Tech Radio, on the web at twatech.org, where you'll find a transcript of this show and all the links I've mentioned. Shouts to Droops, Mr p0trill0, all the content providers that keep TWAT on the air and all of you folks for listening. Remember that if you've got any information to share, this'd be a fine place to do the sharing. My name's kynan and if you've got any comments or suggestions then drop me a line at kynan@kynan.org Thanks for listening. - Outro Music -