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.
Table of Contents
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.
- (2.1.3.) WMIC: “WMIC” stands for “Windows Management Instrumentation Command-line”.
- (2.1.4.) PowerShell: A task automation and configuration management framework.
NOTE: NET can only be used locally, whereas SC can be used locally and remotely.
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!
Thanks for the great article. I was familiar with the local stuff, but hadn’t worked with the remote capability yet. Much appreciated!