Windows

Managing Windows Services from CLI

In this short guide, I’ll be reviewing the necessary information for how to manage services from the command line on Windows workstations and servers. It should also go without saying that “services” are an integral part of pretty much all computer systems. You should also be aware that “services” are sometimes referred to as daemons (pronounced “demons”), especially in various *nix-based operating systems.

1. Managing Windows Services Introduction

There are multiple ways to manage/administer services on Windows workstations and servers, and whichever method(s) you choose to use is generally based on speed/efficiency, and user preference. For instance, while I do  find myself using PowerShell occasionally for a variety of different tasks, I personally always look for simpler, faster alternatives where applicable (batch script, psexec, winrs, wmic, etc). Reason being is that I’ve had so many times where I’ve found code examples online that either contain way more characters and/or lines of code than other methods, or the PowerShell examples I find online don’t always work, or the code examples simply fail with various errors (not to mention missing pre-requisites). I’m not bashing PowerShell by any means, but I also won’t spend 30 minutes trying to get multiple lines of complex PowerShell code to work when I can accomplish the same task in a few seconds with a simple one-line batch command.

NOTE 1:  There are several other management tasks that can be performed when managing services (creating, pausing, etc), but I’ve chosen to cover the ones that I feel will be most relevant and common to someone who’s reading this document.

NOTE 2:  Since a lot of the commands I’m going to be covering need to be entered in an administrative command prompt, I would recommend typing them all from an admin prompt (using the “RunAs Administrator” option when launching “CMD”).

The main tasks that I’ll be covering with regards to managing services are:

  • modify or delete
  • start or stop
  • query

That may not sound like much, but there’s a surprising amount of detail in those five distinct tasks (and I’ll even throw in a few bonuses along the way!).

I’ll cover these options in more detail as we continue through this guide.

2. My List of Tools/Utilities to Manage Services

There’s a variety of tools that can be used, and there are likely other tools that I’m unaware of that could also be used to manage services, but I’m only going to list the ones that I use or am familiar with. The rabbit hole can go real deep on this subject, but I’ll be covering a lot of helpful and relevant information, so stick around and keep reading!

2.1. Native Windows Tools

  • (2.1.1.) SC:  “SC” stands for “service controller”.
  • (2.1.2.) NET:  “NET” essentially stands for “network”, and as such, it can be used to manage network resources.
  •   NOTE:  NET can only be used locally, whereas SC can be used locally and remotely.

  • (2.1.3.) WMIC:  “WMIC” stands for “Windows Management Instrumentation Command-line”.
  • (2.1.4.) PowerShell:  A task automation and configuration management framework.

2.2. Third-Party and/or Non-Native Tools

  • (2.2.1.) PsService:  The “Ps” in all of the various PsTools got its name due to the fact that the standard UNIX process listing command-line tool is named “ps”, so Mark Russinovich (the creator of the PsTools suite) adopted this prefix for all the tools in order to tie them together into a suite of tools named PsTools. One of the nice features of PsService is that you can input credentials for authentication! (this is not possible with SC)
  • (2.2.2.) RemoteService:  It’s not natively possible to restart services remotely AND  input credentials for authentication, but this tool can! (just like PsService)

2.3. Bonus: Extra Tools & Tips

  • (2.3.1.) PsExec:  PsExec is also part of the PsTools suite, and it can be used in combination with other tools.
  • (2.3.2.) WinRS:  “WinRS” stands for Windows Remote Shell, and it’s a natively available tool in Windows. WinRS can also be used in combination with other tools.

Alright, let’s begin looking at each of these tools!

(2.1. Native Windows Tools)

2.1.1. SC

NOTE:  One major difference between SC and NET is this: SC will send a control request to a service and then immediately return to the prompt, whereas NET will wait for the service to respond before it returns to the prompt. What’s the significance of this? If anything, it’s at least good to know that NET will do the work for you in terms of “the waiting game”, whereas SC will tell you what it did, but it’s up to you to make sure it was successful. Don’t let this info be a deterrent though when it comes to using SC. SC is an amazing little utility that you’ll really enjoy using!

The native help for SC is as follows:

USAGE:
        sc  [command] [service name]  ...

        The option  has the form "\\ServerName"
        Further help on commands can be obtained by typing: "sc [command]"
        Commands:
          query-----------Queries the status for a service, or enumerates the status for types of services.
          queryex---------Queries the extended status for a service, or enumerates the status for types of services.
          start-----------Starts a service.
          pause-----------Sends a PAUSE control request to a service.
          interrogate-----Sends an INTERROGATE control request to a service.
          continue--------Sends a CONTINUE control request to a service.
          stop------------Sends a STOP request to a service.
          config----------Changes the configuration of a service (persistent).
          description-----Changes the description of a service.
          failure---------Changes the actions taken by a service upon failure.
          failureflag-----Changes the failure actions flag of a service.
          sidtype---------Changes the service SID type of a service.
          privs-----------Changes the required privileges of a service.
          qc--------------Queries the configuration information for a service.
          qdescription----Queries the description for a service.
          qfailure--------Queries the actions taken by a service upon failure.
          qfailureflag----Queries the failure actions flag of a service.
          qsidtype--------Queries the service SID type of a service.
          qprivs----------Queries the required privileges of a service.
          qtriggerinfo----Queries the trigger parameters of a service.
          qpreferrednode--Queries the preferred NUMA node of a service.
          delete----------Deletes a service (from the registry).
          create----------Creates a service. (adds it to the registry).
          control---------Sends a control to a service.
          sdshow----------Displays a service's security descriptor.
          sdset-----------Sets a service's security descriptor.
          showsid---------Displays the service SID string corresponding to an arbitrary name.
          triggerinfo-----Configures the trigger parameters of a service.
          preferrednode---Sets the preferred NUMA node of a service.
          GetDisplayName--Gets the DisplayName for a service.
          GetKeyName------Gets the ServiceKeyName for a service.
          EnumDepend------Enumerates Service Dependencies.

        The following commands don't require a service name:
        sc   
          boot------------(ok | bad) Indicates whether the last boot should be saved as the last-known-good boot configuration
          Lock------------Locks the Service Database
          QueryLock-------Queries the LockStatus for the SCManager Database
EXAMPLE:
        sc start MyService

QUERY and QUERYEX OPTIONS:
        If the query command is followed by a service name, the status for that service is returned.  Further options do not apply in this case.  If the query command is followed by nothing or one of the options listed below, the services are enumerated.

    type=    Type of services to enumerate (driver, service, all)
             (default = service)
    state=   State of services to enumerate (inactive, all)
             (default = active)
    bufsize= The size (in bytes) of the enumeration buffer
             (default = 4096)
    ri=      The resume index number at which to begin the enumeration
             (default = 0)
    group=   Service group to enumerate
             (default = all groups)

SYNTAX EXAMPLES
sc query                - Enumerates status for active services & drivers
sc query eventlog       - Displays status for the eventlog service
sc queryex eventlog     - Displays extended status for the eventlog service
sc query type= driver   - Enumerates only active drivers
sc query type= service  - Enumerates only Win32 services
sc query state= all     - Enumerates all services & drivers
sc query bufsize= 50    - Enumerates with a 50 byte buffer
sc query ri= 14         - Enumerates with resume index = 14
sc queryex group= ""    - Enumerates active services not in a group
sc query type= interact - Enumerates all interactive services
sc query type= driver group= NDIS     - Enumerates all NDIS drivers

As you can see, there’s a decent amount of options, so I’m not going to be covering every detail of what you could do with SC. I will however provide some examples of how I personally utilize it.

In this next section, I’m going to show you some basic SC examples.

2.1.1a. SC “Query”

Anytime you want to know what services are installed on a computer, you can use the query command. If you simply run sc query, you’ll get a long list of every service that is installed and  running. Here’s an example command with one section of output (I’m only listing one service result as an example because the entire list would be overkill for this demonstration):

sc query

SERVICE_NAME: AeLookupSvc
DISPLAY_NAME: Application Experience
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

Or if you’d like to discover every service that’s installed, whether it’s running or not, you can use sc query state= all. Here’s an example (again, with only one section of output):

sc query state= all

SERVICE_NAME: WwanSvc
DISPLAY_NAME: WWAN AutoConfig
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 1077  (0x435)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

If you’d like to query a remote workstation, simply add \\<computername> like this:

sc \\<computername> query state= all

(of course you'll want to substitute <computername> with the actual computer name)

If you’re looking for a specific service, you can use sc query <service_name>. Here’s an example of querying the “WWAN AutoConfig” service:

sc query wwansvc

SERVICE_NAME: wwansvc
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 1077  (0x435)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

If you’d like to see the configuration information for a specific service, you can use sc qc <service_name>. Here’s an example of querying the configuration info for the “WWAN AutoConfig” service:

sc qc wwansvc
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: wwansvc
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 3   DEMAND_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
        LOAD_ORDER_GROUP   : TDI
        TAG                : 0
        DISPLAY_NAME       : WWAN AutoConfig
        DEPENDENCIES       : PlugPlay
                           : RpcSs
                           : NdisUio
                           : NlaSvc
        SERVICE_START_NAME : NT Authority\LocalService

2.1.1b. SC “Stop” and “Start”

The most common thing I use SC for is to stop and start services (like restarting the print spooler service for example). Piggybacking off my spooler reference there, here’s an example (with output) of restarting the print spooler service (its service name is simply “spooler”):

sc stop spooler

SERVICE_NAME: spooler
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        STATE              : 3  STOP_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x3
        WAIT_HINT          : 0x4e20
sc start spooler

SERVICE_NAME: spooler
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        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                : 51156
        FLAGS              :

If you’d like to concatenate the commands, you can do it like this:

sc stop spooler & sc start spooler

Remember that you can use these functions to control remote services as well, like this:

sc \\<computername> stop spooler
sc \\<computername> start spooler

(or concatenated)

sc \\<computername> stop spooler & sc \\<computername> start spooler

Sometimes you may want to script this process, and you may need to incorporate a timeout (which is essentially a timed pause) to prevent your commands from “jumping the gun” so to speak. Here’s an example of using a batch script to restart a service (with a 15 second timeout after sending the stop command, and a 5 second timeout after sending the start command):

@echo off
sc stop <service_name>
TIMEOUT /T 15
sc start <service_name>
TIMEOUT /T 5
exit

Using timeouts can be very handy when you need to give services time to gracefully stop or start.

2.1.1c. SC “Config”

The config command, when used with SC, will enable you to persistently change the configuration of a service (for example, to set a service to start automatically).

You may have no use for the “Windows Media Player Network Sharing Service”, so you could set it to disabled  by using the following command:

sc config WMPNetworkSvc start= disabled

(note: the space after "start=" is important!)

If you want a service to always start automatically, you would simply choose auto  instead of disabled. Here’s an example of configuring the Remote Registry service to start automatically:

sc config RemoteRegistry start= auto

2.1.1d. SC “Delete”

There likely won’t be many instances where you’ll need to delete a service, but this is still a helpful command to know. The most common thing I use it for is to delete the PsExec service from a remote machine when it gets “stuck”.

NOTE:  The above info is important to be aware of because there are times when you’ll attempt to connect with PsExec to a remote machine and you’ll get a message like this:

Error establishing communication with PsExec service on site1-pc1:
The system cannot find the file specified.

This message occurs because the PsExec service already exists and  is running on the remote machine. A stop command usually fixes this:

sc \\site1-pc1 stop psexesvc

But there are other times when the service exists, but it’s not  running, and in those cases you’ll need to delete the service, like this:

sc \\site1-pc1 delete psexesvc

(note: the missing "c" in "psexesvc" is not a typo; that's the exact service name for the PsExec service)

(2.1.1. Surprise Bonus! SC "Create")

The create  option basically enables you to register an application as a service! “Why would I want to do that?”, you ask? Consider this scenario:

You have a webcam connected to your computer, and you have it configured while you’re away to start recording video if it detects movement. However, one of the caveats is that the camera app needs to be running. But you say “Why is that a big deal!? I can start the app and let it run while I’m away!”. Well, what if while you’re away, your computer has one of those rare times where it reboots for no reason? Or what if you forget to start the app before you leave? Then your camera app won’t be running, so it won’t be able to record video. But if you register the camera app as a service, it’ll be running as soon as Windows is running (whether you’re logged on or not!).

So here’s how you would register that app as a service: Let’s say your app is called “Camera App” and it’s located in C:\!Central\Apps\Camera App\ and the name of the app is camera_app.exe. Here’s how you would create a service from this app:

First let me show you the syntax for creating a service with SC:

USAGE:
        sc  create [service name] [binPath= ]  ...

OPTIONS:
NOTE: The option name includes the equal sign.
      A space is required between the equal sign and the value.
 type= 
       (default = own)
 start= 
       (default = demand)
 error= 
       (default = normal)
 binPath= 
 group= 
 tag= 
 depend= 
 obj= 
       (default = LocalSystem)
 DisplayName= 
 password= 

OK, so here’s the command to create a service from our “Camera App” example:

sc create camera displayname= "Camera App" binpath= "C:\!Central\Apps\Camera_App\camera_app.exe" start= auto
[SC] CreateService SUCCESS

Pretty cool stuff, eh!? : )

2.1.2. NET

Net can be used to perform a variety of functions (not just controlling services). For this particular guide, I’ll only be covering a couple of examples as they relate to controlling services.

The native help for NET (specifically with regards to services) is as follows:

Syntax
      NET START [service]
      NET STOP [service]
      NET PAUSE [service]
      NET CONTINUE [service] 
Key
   service : The service name as shown in Control Panel, Services

NOTE 1:  As you can see in the syntax above, there’s an option to pause or continue a service. I’ve personally never used these functions, so I won’t be covering examples for them in this guide. You at least know about them if you decide you’d like to utilize those functions.

NOTE 2:  It’s actually possible to use the NET command to verify if a service is running, but it’s a little more cumbersome compared to using SC, so I won’t be covering that info in this guide either.

Here’s an example of restarting the print spooler service:

net stop spooler
The Print Spooler service is stopping.
The Print Spooler service was stopped successfully.
net start spooler
The Print Spooler service is starting.
The Print Spooler service was started successfully.

2.1.3. WMIC

I personally can’t think of any instances where WMI would be the best option to stop or start a service (because something like SC is more efficient), but I’ll at least provide the basics of how to use it to stop and start services.

Here’s an example of stopping the print spooler service (line 1 is the command, and lines 2-8 are the output):

wmic service where "name = 'spooler'" call stopservice
Executing (\\IT-SHUEY-PC1\ROOT\CIMV2:Win32_Service.Name="Spooler")->stopservice()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ReturnValue = 0;
};

And here’s the command to verify that the service stopped (line 1 is the command, and lines 2-3 are the output):

wmic service where "name = 'spooler'" get started
Started
FALSE

Here’s an example of starting the print spooler service, and then verifying that it’s started:

wmic service where "name = 'spooler'" call startservice
Executing (\\IT-SHUEY-PC1\ROOT\CIMV2:Win32_Service.Name="Spooler")->startservice()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ReturnValue = 0;
};
wmic service where "name = 'spooler'" get started
Started
TRUE

Here’s an example of using WMI to verify the state of the spooler service on a remote machine (“SITE1-PC1” is the name of the remote station in my example):

wmic /node:"SITE-PC1" service where caption='print spooler' get state
State
Running

Here’s an even shorter example using where name (instead of where caption) which allows using the service name instead of the full name (spooler instead of print spooler):

wmic /node:"SITE-PC1" service where name='spooler' get state
State
Running

(2.1.3. Surprise Bonus! Alternate WMI Commands)

There’s a lot of cool stuff you can do with WMI, beyond just controlling services. Here’s a couple of examples:

Verifying the BIOS version of a remote computer:

wmic /node:"site1-pc1" bios get smbiosbiosversion
SMBIOSBIOSVersion
K01 v03.04

Verifying the serial number of a remote computer:

wmic /node:"site1-pc1" systemenclosure get serialnumber
SerialNumber
ZX583PP1

2.1.4. PowerShell

As I said before, I personally have found that SC is more effective for managing services, but PowerShell is still preferred by some people for various reasons. I’ll provide some brief info and examples of how PowerShell can be used to manage services.

To see which cmdlets are available for the use of managing services, type:

get-command -noun service

Notice the output:

CommandType     Name                    Definition
------		---------------		--------------------------------------------------------
Cmdlet		Get-Service		    Get-Service [[-Name] ] [-ComputerName <String[...
Cmdlet		New-Service		    New-Service [-Name]  [-BinaryPathName]  ...
Cmdlet		Restart-Service		Restart-Service [-Name]  [-Force] [-PassThru] ...
Cmdlet		Resume-Service		Resume-Service [-Name]  [-PassThru] [-Include ...
Cmdlet		Set-Service		    Set-Service [-Name]  [-ComputerName ] ...
Cmdlet		Start-Service		Start-Service [-Name]  [-PassThru] [-Include <...
Cmdlet		Stop-Service		Stop-Service [-Name]  [-Force] [-PassThru] [-I...
Cmdlet		Suspend-Service		Suspend-Service [-Name]  [-PassThru] [-Include...

Notice that PowerShell has a Restart-Service cmdlet, which combines the stop and start functionality into one cmdlet. You of course still have the option of using Stop-Service and Start-Service separately one-at-a-time.

If you’d like help for a particular cmdlet, type:

get-help <cmdlet_name>

Here’s an example of getting help for the Get-Service cmdlet:

get-help get-service

NAME
    Get-Service

SYNOPSIS
    Gets the services on a local or remote computer.

SYNTAX
    Get-Service [[-Name] ] [-ComputerName ] [-DependentServices] [-Exclude ] [-Include ] [-RequiredServices] []
    
    Get-Service -DisplayName  [-ComputerName ] [-DependentServices] [-Exclude ] [-Include ] [-RequiredServices] []
    
    Get-Service [-InputObject ] [-ComputerName ] [-DependentServices] [-Exclude ] [-Include ] [-RequiredServices] []

DESCRIPTION
    The Get-Service cmdlet gets objects that represent the services on a local computer or on a remote computer, including running and stopped services. 

    You can direct Get-Service to get only particular services by specifying the service name or display name of the services, or you can pipe service objects to Get-Service.

RELATED LINKS
    Online version: http://go.microsoft.com/fwlink/?LinkID=113332
    Start-Service 
    Stop-Service 
    Restart-Service 
    Resume-Service 
    Suspend-Service 
    Set-Service 
    New-Service 

REMARKS
    To see the examples, type: "get-help Get-Service -examples".
    For more information, type: "get-help Get-Service -detailed".
    For technical information, type: "get-help Get-Service -full".

Now I’ll show you an example of what happens when you try to use PowerShell to perform a task as simple as restarting a service. First I’ll show you the syntax for the Restart-Service cmdlet:

SYNTAX
    Restart-Service [-Name]  [-Exclude ] [-Force] [-Include ] [-PassThru] [-Confirm] [-WhatIf] []

    Restart-Service -DisplayName  [-Exclude ] [-Force] [-Include ] [-PassThru] [-Confirm] [-WhatIf] []

    Restart-Service [-InputObject ] [-Exclude ] [-Force] [-Include ] [-PassThru] [-Confirm] [-WhatIf] []

OK, so, based on the syntax example, I would think that this would be fairly easy. But it’s not as easy as you would think. Here’s an example of what happens when I try to restart the spooler service:

restart-service spooler

Restart-Service : Cannot stop service 'Print Spooler (spooler)' because it has dependent services. It can only be stopped if the Force flag is set.
At line:1 char:16
+ restart-service <<<<  spooler
    + CategoryInfo          : InvalidOperation: (System.ServiceProcess.ServiceController:ServiceController) [Restart-Service], ServiceCommandException
    + FullyQualifiedErrorId : ServiceHasDependentServices,Microsoft.PowerShell.Commands.RestartServiceCommand

OK, so it looks like I need to use the -Force flag to get this to work, so here’s an example of what happens when I try using the -Force flag:

restart-service spooler -Force

WARNING: Waiting for service 'Print Spooler (spooler)' to finish starting...

Checking the service with the Get-Service command reveals that the restart of the service was successful:

get-service spooler

Status   Name               DisplayName                           
------   ----               -----------                           
Running  spooler            Print Spooler 

There’s a ton of other commands and things you can do with PowerShell, but that’s outside the scope of this guide.

(2.2. Third-Party and/or Non-Native Tools)

2.2.1. PsService

This tool is similar to SC, but it produces slightly different results.

NOTE:  Something interesting about the PsService tool (and slightly odd in my opinion) is that there is no option to delete a service…

Here’s the syntax for PsService:

Usage: psservice [\\Computer [-u Username [-p Password]]]  
Cmd is one of the following:
   query      Queries the status of a service
   config     Queries the configuration
   setconfig  Sets the configuration
   start      Starts a service
   stop       Stops a service
   restart    Stops and then restarts a service
   pause      Pauses a service
   cont       Continues a paused service
   depend     Enumerates the services that depend on the one specified
   find       Searches for an instance of a service on the network
   security   Reports the security permissions assigned to a service

Use the username and password to log into the remote computer in cases where your account does not have permissions to perform the action you specify.

Omitting a command queries the active services on the specified computer.
Enter -? for help on a particular command.

Here’s an example of the info that PsService produces (querying the remoteregistry  service for example):

psservice \\site1-pc1 query remoteregistry

SERVICE_NAME: RemoteRegistry
DISPLAY_NAME: Remote Registry
Enables remote users to modify registry settings on this computer. If this service is stopped, the registry can be modified only by users on this computer. If this service is disabled, any services that explicitly depend on it will fail to start.
        TYPE              : 20 WIN32_SHARE_PROCESS
        STATE             : 4  RUNNING
                               (STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE   : 0  (0x0)
        SERVICE_EXIT_CODE : 0  (0x0)
        CHECKPOINT        : 0x0
        WAIT_HINT         : 0 ms

Here’s an example of restarting the print spooler service:

psservice restart spooler

SERVICE_NAME: spooler
DISPLAY_NAME: Print Spooler
Loads files to memory for later printing
        GROUP             : SpoolerGroup
        TYPE              : 110 WIN32_OWN_PROCESS INTERACTIVE_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         : 2000 ms

Here’s an example of querying the print spooler service:

psservice query spooler

SERVICE_NAME: Spooler
DISPLAY_NAME: Print Spooler
Loads files to memory for later printing
        GROUP             : SpoolerGroup
        TYPE              : 110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS
        STATE             : 4  RUNNING
                               (STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE   : 0  (0x0)
        SERVICE_EXIT_CODE : 0  (0x0)
        CHECKPOINT        : 0x0
        WAIT_HINT         : 0 ms

Remember how SC can show configuration info with qc ? With PsService, it’s done using the config command. Here’s an example with the spooler service:

psservice config spooler

SERVICE_NAME: Spooler
DISPLAY_NAME: Print Spooler
Loads files to memory for later printing
        TYPE              : 110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS
        START_TYPE        : 2  AUTO_START
        ERROR_CONTROL     : 1  NORMAL
        BINARY_PATH_NAME  : C:\Windows\System32\spoolsv.exe
        LOAD_ORDER_GROUP  : SpoolerGroup
        TAG               : 0
        DEPENDENCIES      : RPCSS
                          : http
        SERVICE_START_NAME: LocalSystem
        FAIL_RESET_PERIOD : 86400 seconds
        FAILURE_ACTIONS   : Restart     DELAY: 60000 seconds
                          : Restart     DELAY: 60000 seconds
                          : None        DELAY: 0 seconds

Here’s an example of setting the WMPNetworkSvc to disabled :

psservice setconfig wmpnetworksvc disabled

Start type of wmpnetworksvc on \\SITE1-PC1 set to disabled.

And as I mentioned back in the beginning of section 2, PsService can also be used to input credentials on remote machines! Here’s an example of restarting the spooler service on a remote machine, using the appropriate credentials:

psservice \\site1-pc1 -u admin -p P@ssw0rd restart spooler

SERVICE_NAME: spooler
DISPLAY_NAME: Print Spooler
Loads files to memory for later printing
        GROUP             : SpoolerGroup
        TYPE              : 110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS
        STATE             : 2  START_PENDING
                               (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE   : 0  (0x0)
        SERVICE_EXIT_CODE : 0  (0x0)
        CHECKPOINT        : 0x2
        WAIT_HINT         : 20000 ms

2.2.2. RemoteService

This is a cool little free utility from Steve Wiseman  of IntelliAdmin! One of the biggest benefits of this tool is that, like PsService, it can be used to input credentials against remote machines. However, it’s a little more limited than PsService, in terms of command actions (it only allows you to stop  or start  a service)

Here’s the usage:

remoteservice /?
*************************************************************************
* IntelliAdmin Remote Service                                           *
* Stop or start services - remotely                                     *
* Usage:                                                                *
* RemoteService.exe    [USERNAME] [PASSWORD]                            *
* Possible Actions: STOP, START                                         *
* Username and password are optional values                             *
* ----------------------------------------------------------------------*
* More Free Utilities at: http://www.intelliadmin.com                   *
*************************************************************************

And here’s a syntax example:

remoteservice.exe <remote_computer_name_or_ip> <action> <service_name> <username> <password>

Here’s an example of stopping the spooler service:

remoteservice.exe site1-pc1 stop spooler admin P@ssw0rd

-Authenticating with \\site-pc1
-Authentication complete
-Stopping service
-Service stopped

(2.3. Bonus: Extra Tools & Tips)

2.3.1. PsExec

PsExec is one of my best friends when it comes to remote management! It’s one of those tools that can  be used to manage services, but the likelihood of using it for that is slim to none (but I couldn’t resist including it in this guide, because of how powerful it is!). Let’s look at some of the cool things you can do with it!

First let’s look at the syntax:

psexec /?

PsExec executes a program on a remote system, where remotely executed console applications execute interactively.

Usage: psexec [\\computer[,computer2[,...] | @file]][-u user [-p psswd][-n s][-r servicename][-h][-l][-s|-e][-x][-i [session]][-c [-f|-v]][-
w directory][-d][-][-a n,n,...] cmd [arguments]
     -a         Separate processors on which the application can run with
                commas where 1 is the lowest numbered CPU. For example,
                to run the application on CPU 2 and CPU 4, enter:
                "-a 2,4"
     -c         Copy the specified program to the remote system for
                execution. If you omit this option the application
                must be in the system path on the remote system.
     -d         Don't wait for process to terminate (non-interactive).
     -e         Does not load the specified account's profile.
     -f         Copy the specified program even if the file already
                exists on the remote system.
     -i         Run the program so that it interacts with the desktop of the
                specified session on the remote system. If no session is
                specified the process runs in the console session.
     -h         If the target system is Vista or higher, has the process
                run with the account's elevated token, if available.
     -l         Run process as limited user (strips the Administrators group
                and allows only privileges assigned to the Users group).
                On Windows Vista the process runs with Low Integrity.
     -n         Specifies timeout in seconds connecting to remote computers.
     -p         Specifies optional password for user name. If you omit this
                you will be prompted to enter a hidden password.
     -r         Specifies the name of the remote service to create or interact.
                with.
     -s         Run the remote process in the System account.
     -u         Specifies optional user name for login to remote
                computer.
     -v         Copy the specified file only if it has a higher version number
                or is newer on than the one on the remote system.
     -w         Set the working directory of the process (relative to
                remote computer).
     -x         Display the UI on the Winlogon secure desktop (local system
                only).
     -arm       Specifies the remote computer is of ARM architecture.
     -priority  Specifies -low, -belownormal, -abovenormal, -high or
                -realtime to run the process at a different priority. Use
                -background to run at low memory and I/O priority on Vista.
     computer   Direct PsExec to run the application on the remote
                computer or computers specified. If you omit the computer
                name PsExec runs the application on the local system,
                and if you specify a wildcard (\\*), PsExec runs the
                command on all computers in the current domain.
     @file      PsExec will execute the command on each of the computers listed
                in the file.
     cmd            Name of application to execute.
     arguments  Arguments to pass (note that file paths must be
                absolute paths on the target system).
     -accepteula This flag suppresses the display of the license dialog.
     -nobanner   Do not display the startup banner and copyright message.

You can enclose applications that have spaces in their name with quotation marks e.g. psexec \\marklap "c:\long name app.exe". Input is only passed to the remote system when you press the enter key, and typing Ctrl-C terminates the remote process.

If you omit a user name the process will run in the context of your account on the remote system, but will not have access to network resources (because it is impersonating). Specify a valid user name in the Domain\User syntax if the remote process requires access to network resources or to run in a different account. Note that the password and command is encrypted in transit to the remote system.

Error codes returned by PsExec are specific to the applications you execute, not PsExec.

Now let’s look at one of my favorite things you can do with PsExec –> launch a remote command prompt!

psexec \\site1-pc1 -s cmd

The first time you type that, it may not look like anything happened, but if you look at the title bar of your command prompt window, it should indicate that you’re connected to the remote machine (\\site1-pc1: cmd in my example). You can double-check by typing hostname and verifying the output:

hostname
SITE1-PC1

OK, so what’s so cool about being connected to a remote command prompt? Well, you can run a lot of the same commands that you would run if you were actually physically sitting at the remote computer! An example of where this can be powerful is if you need to run commands that are more challenging to run otherwise (like if you were going to run a bunch of netsh advfirewall commands; it’s nice to be able to connect to the remote machine and then run everything from there once you’re connected).

Alright, so to maintain officiality, let me show you an example of managing a service. Here’s an example of stopping and starting the print spooler service on SITE1-PC1:

psexec \\site1-pc1 -s cmd /c "sc stop spooler"

SERVICE_NAME: spooler
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        STATE              : 3  STOP_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x3
        WAIT_HINT          : 0x4e20
cmd exited on site1-pc1 with error code 0.
psexec \\site1-pc1 -s cmd /c "sc start spooler"

SERVICE_NAME: spooler
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        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                : 1056
        FLAGS              :
cmd exited on site1-pc1 with error code 0.

NOTE:  The /c after cmd tells the shell to run the command and then terminate. I like to think of it like this: you’re essentially telling the shell, “Hey, go over there and run that command, then come back here to me”. If you wanted the shell to run the command and wait at the remote computer for more instructions, you would use a /k instead of /c.

There’s a lot more you can do with PsExec, but that would require a separate dedicated guide.

2.3.2. WinRS

This is another one of those built-in tools in Windows that you can do a lot with (and not just in terms of managing services). And as a matter of fact, I would say that you’ll likely never use WinRS to manage services, but it’s too cool of a utility to not mention it! Two things that I often use WinRS for are:

  • To send Wake-On-LAN (WOL) commands to machines that are powered off
  • To instruct workstations to check for Windows updates, and then report their status to our WSUS server

NOTE 1:  Remember, just based on its name alone, WinRS is used to execute commands on “remote” machines.

NOTE 2:  One very important thing to be aware of with regards to WinRS is that it requires WinRM. Per Microsoft’s definition, “Windows Remote Management (WinRM) is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (SOAP)-based, firewall-friendly protocol that allows hardware and operating systems, from different vendors, to interoperate.” I’ll provide more info about WinRM in a moment.

The chances of someone using WinRS to manage services is highly unlikely, but to stay in line with the purpose of this guide, here’s at least one example of how it can be used; stopping the print spooler on “SITE1-PC1”:

winrs -r:site1-pc1 sc stop spooler

SERVICE_NAME: spooler
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        STATE              : 3  STOP_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x3
        WAIT_HINT          : 0x4e20

OK, so as I stated earlier, WinRS depends on WinRM. If WinRM is not running or not configured on the remote machine that you’re trying to manage, then you may see an error like this:

Winrs error:The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig".

In an instance like that, the first thing you can do is start the service and then try to query it again once it’s running. The easiest/fastest way to start the service remotely is like this (using “SITE1-PC1” as the reference example):

sc \\site1-pc1 start winrm

After that, you can try to remotely query the service to verify if it’s running. Here’s the command:

winrs -r:site1-pc1 sc query winrm

If the service is running, you should see something like this:

SERVICE_NAME: winrm
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

If you’re still getting an error message, the next step would be to configure WinRM on the remote station. WinRM can be configured from a variety of ways (with each method being handy in its own right):

Locally via “Quick Configure” (from and admin cmd prompt):

winrm qc

Or remotely via PsExec (again, via an admin cmd prompt):

psexec \\site1-pc1 -s winrm.cmd qc

Or via group policy (Create or edit a GPO with the following settings):

Computer Configuration
  Policies
    Administrative Templates
      Windows Components Windows Remote Management (WinRM)
        WinRM Service
           Allow automatic configuration of listeners
           Set this to "Enabled" and either specify specific addresses, or use "*" in both filters (IPv4 and IPv6)

(2.3. Surprise WinRS Bonus Tip!)

You didn’t think I was gonna leave you hangin’ with that little bit of WinRS info, did ya!? No way, lol! Remember the two main things that I said I use WinRS for? Well I’m going to show you those commands so you don’t leave here with your glass half-full. Let’s fill that thing to the brim!

Using WinRS to send WOL commands

There’s a few things you should be aware of when it comes to sending WOL commands:

  • The PC that you’re sending the WOL command to must be capable of receiving “magic packets” (The PC needs to have WOL enabled in the BIOS)
  • For the majority of company LANs, it’s not possible to send magic packets through routers (in general, you’re limited to sending them from within the same subnet)
  • Sometimes the NIC adapter from within Windows also needs to be enabled to allow magic packets

LANs can differ greatly from one company to the next, so I’m going to share how I  send magic packets in our network. And if your network is similar to ours, you’ll be able to easily duplicate the methods I’ll be showing you. If not, the concept and tools will still be similar and you should have no problem adapting them to your environment. First I’ll briefly explain how I send magic packets in our network, then I’ll provide more details about the tools/techniques I use.

We have multiple sites with different subnets at each site, and they’re all connected via fiber. So whenever I want to send a magic packet to wake up a machine, I use another computer that’s on the same subnet as the computer that I want to wake up; this other computer acts as a “middle-man PC”. The reason I do it this way, instead of sending the packet directly from my own subnet, is because it never fails using this method. I do this using a free, portable app called MC-WOL. In our network, I used PDQ Deploy to deploy the mc-wol.exe file to every computer in our LAN (My PDQ script copies the file to the C:\Windows\System32 folder on each machine).

In the past, before I knew about WinRS, I would first use PsExec to connect to an online PC that’s in the same subnet as the machine I wanted to wake up:

psexec \\middle-man-pc -s cmd

Then I’d send the magic packet:

mc-wol AB:CD:EF:01:23:45

(note: I just entered a generically formatted MAC address there as an example)

But now that I’m familiar with and use WinRS, I can use a single command:

winrs -r:middle-man-pc mc-wol AB:CD:EF:01:23:45

And, as promised, here’s the WinRS tip relating to WSUS:

Using WinRS to instruct workstations to report-in with their WSUS server

If you personally have access to your company’s WSUS server, remote in and open up the Update Services GUI console so you can see the report status of the computer you’re wanting to update. If you don’t  have direct access to your WSUS server, have one of your WSUS admins verify the computer’s report status for you after you execute the commands.

The first thing you need to do is instruct the remote computer to check for updates from the WSUS server:

winrs -r:remote-pc wuauclt /detectnow

Then you need to instruct the computer to report-in with the WSUS server:

winrs -r:remote-pc wuauclt /reportnow

You should now be able to see an updated time stamp under the “Last Status Report” column in the WSUS console on the server.

NOTE:  (per Lawrence Garvin of WSUS online fame) A couple of very important points to keep in mind when using /detectnow and /reportnow:

The /reportnow function is only processed when:

  • There are completed events to report to the WSUS server
  • The WUAgent is IDLE

The WUAgent always automatically executes a reporting event approximately 20 minutes after the completion of all other pending activities. The purpose of the /reportnow parameter is to immediately expire that 20 minute delay. So, when executing a script with these two commands in immediate succession (or issuing them from the command line immediately following one another), the reality is that the wuauclt /reportnow invocation actually does nothing at all.

The proper way to use these two commands is to first launch the wuauclt /detectnow task, and then WAIT for the completion of the detection event. Typically this could take a couple of minutes, but on a healthy, fully patched system, it may complete in a matter of seconds.

Once the WUAgent is idle, then executing wuauclt /reportnow will cause the call to the ReportingWebService to occur immediately, rather than waiting for the built-in 20 minute delay.

3. Summary

There’s definitely no shortage of options when it comes to managing Windows services from the CLI, and it’s nice that the primary ones are already built-in to the Windows operating system. Not only that, but there are some great third-party tools available as well (some of the best of which were actually created by a Microsoft employee!).

I hope this guide is not only helpful, but also gets you excited to dive deeper into the realm of managing services on Windows machines!

John Schuepbach

I've been tinkering with computers since 1984 and have been working professionally in the field of IT since 2005. I love learning about new technology and always enjoy figuring out how things work. People also say that I'm a freak about detail and organization - I take that as a compliment ;). I'm commonly known as "Shuey". I'm known for my passionate obsession of all things that interest me; particularly computers, video games (like Tetris), music, art, etc.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jim Compton
Jim Compton
6 years ago

Thanks for the great article. I was familiar with the local stuff, but hadn’t worked with the remote capability yet. Much appreciated!

Back to top button