Managing Windows Services with PowerShell. Part 2

Original author: Jeff Hicks
  • Transfer
  • Tutorial

We continue to learn how to manage Windows services using PowerShell. In a previous post, we looked at how to get the status of a service on a local and remote computer, filter services (for example, find only stopped services) and determine dependent services. In this post, such trivial things as:
  1. Service stop
  2. Service start
  3. Service restart
  4. Pause and resume work
  5. Remote Services Management
  6. Configure service startup

We will pay more attention to parsing commands in PowerShell to implement the above on the local computer. In the “Managing Remote Computer Services” section, we look at the limitations of working in PowerShell v2 and v3. Details under the cut.

Previous article:
Managing Windows Services with PowerShell. Part 1. Getting the status of services


PS C:\> get-service bits
Status Name DisplayName
------ ---- -----------
Running bits Background Intelligent Transfer Ser...

Since the command for obtaining the status of the service is called Get-Service , it will not be difficult to guess how other commands are written. At worst, we can ask PowerShell about all the commands that are somehow related to working with services. Note that we used the –noun parameter to get all the commands related to services.



Take a closer look at these commands.

STOP-SERVICE


To stop the service, we must clarify its name.

PS C:\> stop-service wuauserv


However, nothing will be transferred to the conveyor. Some cmdlets, such as Stop-Service , are designed so that by default they do not write the object to the pipeline. We will force it to do this using the –Passthru parameter .

PS C:\> stop-service bits -PassThru
Status Name DisplayName
------ ---- -----------
Stopped bits Background Intelligent Transfer Ser...


If the service is not running, then the cmdlet will not output anything, nor will it produce any error. Therefore, it is sometimes better to transfer the object to the Stop-Service (naturally using the –whatif parameter ).

PS C:\> get-service browser | stop-service -WhatIf
What if: Performing operation “Stop-Service” on Target “Computer Browser (browser)”.


The –WhatIf parameter has been added so that we can see what happens if the cmdlet is run. When I make sure that this is the service that interests me, I just remove -Watif and stop the service.

PS C:\> get-service browser | stop-service


As I mentioned above, if the service is already stopped, then the cmdlet will do nothing. And the use of Stop-Service in this case will not harm anyone. However, I still prefer a more civilized approach, namely:

PS C:\> get-service bits | where {$_.status -eq 'running'} | stop-service -pass
Status Name DisplayName
------ ---- -----------
Stopped bits Background Intelligent Transfer Ser...


If the service is running, the object is transferred to the pipeline and sent to the Stop-Service . The following is an option to stop multiple services.

PS C:\> get-service bits,wsearch,winrm,spooler | where {$_.status -eq 'running'} | stop-service -whatif
What if: Performing operation "Stop-Service" on Target "Print Spooler (spooler)".
What if: Performing operation "Stop-Service" on Target "Windows Remote Management (WS-Management) (winrm)".
What if: Performing operation "Stop-Service" on Target "Windows Search (wsearch)".


Some services will not want to stop - due to the availability of dependent services - which we see in the screenshot below.



In this case, use the –Force parameter . In most cases, this works, but without “foolproof”. Remember that the command will also stop dependent services.

PS C:\> stop-service lanmanserver -force –PassThru
Status Name DisplayName
------ ---- -----------
Stopped Browser Computer Browser
Stopped lanmanserver Server


START-SERVICE



The service is launched in a similar manner. It supports the –Whatif option , and you have to use –Passthru to see objects.

PS C:\> start-service wuauserv -PassThru
Status Name DisplayName
------ ---- -----------
Running wuauserv Windows Update


And again: if the service is already running, the cmdlet will do nothing. However, you can try to start the service and get this error.



The reason for this in most cases is turned off services. How to configure the service settings, I will describe in the next article.
If you want to start services and all services dependent on it, use the following expression:

PS C:\> get-service lanmanserver | Foreach { start-service $_.name -passthru; start-service $_.DependentServices -passthru}
Status Name DisplayName
------ ---- -----------
Running lanmanserver Server
Running Browser Computer Browser


We must explicitly get the dependent services because the Start-Service will not automatically start them.

RESTART-SERVICE



You will be surprised, but restarting the service works the same as the two previous examples. Use –Passthru if you want to make sure that the service is running.

PS C:\> restart-service spooler -PassThru
Status Name DisplayName
------ ---- -----------
Running spooler Print Spooler


Since we are shutting down the service, we may need the –Force parameter .

SUSPENSION AND RESUME OF WORK



Some services may be suspended for a while and then resumed, and we can do this through PowerShell. However, if the service does not meet the requirements, we will receive such errors. (the example shows that we tried to suspend the bits service)



What is the problem? We look at the object (using Get-Service ).

PS C:\> get-service bits | select *
Name : bits
RequiredServices : {RpcSs, EventSystem}
CanPauseAndContinue : False
CanShutdown : False
CanStop : True
DisplayName : Background Intelligent Transfer Service
DependentServices : {}
MachineName : .
ServiceName : bits
ServicesDependedOn : {RpcSs, EventSystem}
ServiceHandle : SafeServiceHandle
Status : Running
ServiceType : Win32ShareProcess
Site :
Container :


If the CanPauseAndContinue property value is True , then we can pause and resume the service. Find the following services:

PS C:\> get-service | where {$_.CanPauseandContinue}
Status Name DisplayName
------ ---- -----------
Running LanmanServer Server
Running LanmanWorkstation Workstation
Running MSSQLSERVER SQL Server (MSSQLSERVER)
Running O2FLASH O2FLASH
Running stisvc Windows Image Acquisition (WIA)
Running Winmgmt Windows Management Instrumentation


As we can see, not many services satisfy this requirement.

PS C:\> suspend-service o2flash -PassThru
Status Name DisplayName
------ ---- -----------
Paused O2FLASH o2flash


Ready to resume service? Use the following expression:

PS C:\> resume-service o2flash -PassThru
Status Name DisplayName
------ ---- -----------
Running O2FLASH o2flash


Both cmdlets also support –Whatif .

REMOTE SERVICES



As you might have noticed, we demonstrated all the examples above on the local machine. And this is no coincidence. Unfortunately, even in PowerShell v3, none of these cmdlets have a parameter that allows you to manage the service on a remote computer. Get-Service , of course, supports the –Computername parameter , but no more. You can see the service, but you won’t be able to do anything with it. No, you can, of course, if the remote computer is running PS v2 and PowerShell Remoting is enabled. Then we can use all of the above commands using Invoke-Command for the remote computer or PSSession . On the other hand, it’s easier to manage one service on multiple servers.

PS C:\> Invoke-Command {restart-service dns –passthru} –comp chi-dc03,chi-dc02,chi-dc01




Managing services on remote computers is not limited to the above, but this will be the subject of consideration in subsequent articles.
All of these cmdlets can be used in pipelined terms and this is often the best option. Using Get-Service to get objects and then passing them to a suitable cmdlet.

SET THE REMOTE STATUS



So, we found out that the Stop-Service cmdlet lacks such a useful parameter as –Computername . We can use these commands in a remote session by contacting the Invoke-Command cmdlet , which in itself is productive if you work with the service on multiple computers. One can start, stop, restart, pause and restart using Set-Service .

PS C:\> set-service wuauserv -ComputerName chi-dc03 -Status stopped -WhatIf
What if: Performing operation "Set-Service" on Target "Windows Update (wuauserv)".


This command supports the –WhatIf parameter . You should also use –Passthru to transfer objects to the pipeline.

PS C:\> set-service bits -ComputerName chi-dc03 -Status running -PassThru
Status Name DisplayName
------ ---- -----------
Running bits Background Intelligent Transfer Ser...


Valid values ​​for the –Status parameter are “running”, “stopped” (stopped) and “paused”. Remember that the service has dependent services, we won’t be able to change it, as shown in the screenshot below.



Unfortunately, Set-Service lacks the –Force option , so you'll have to revert to using PowerShell remoting and Invoke-Command . If you want to restart the remote service, use the following command:

PS C:\> set-service w32time -ComputerName chi-dc03 -Status Stopped -PassThru | set-service -PassThru -Status Running
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time


Remember to use –Passthru , otherwise the second Set-Service command will not do anything.
As for me, I prefer to work with several services at once, which I cannot stop remotely using Set-Service, although their launch is a problem. I am using Invoke-Command . But remember that using the –Computername parameter , PowerShell connects using RPC and DCOM, which can lead to problems with the firewall. Invoke-Command uses PowerShell remoting, which we may not have yet configured or enabled.

SETTING SERVICE START TYPE



Set-Service is useful when you want to enable or disable a service using the –StartupType parameter . If you configured the service using Automatic, Manual, or Disabled. Unfortunately, there is no option for Automatic (Delayed).

PS C:\> set-service remoteregistry -StartupType Manual -WhatIf
What if: Performing operation "Set-Service" on Target "Remote Registry (remoteregistry)".
PS C:\> set-service remoteregistry -StartupType Manual -PassThru
Status Name DisplayName
------ ---- -----------
Stopped remoteregistry Remote Registry


However, just by looking at the object, we will not be able to tell what type of startup it refers to.

PS C:\> get-service remoteregistry | select *
Name : remoteregistry
RequiredServices : {RPCSS}
CanPauseAndContinue : False
CanShutdown : False
CanStop : False
DisplayName : Remote Registry
DependentServices : {}
MachineName : .
ServiceName : remoteregistry
ServicesDependedOn : {RPCSS}
ServiceHandle : SafeServiceHandle
Status : Stopped
ServiceType : Win32ShareProcess
Site :
Container :


How to do this is one of the topics of the next article.
Remember that changing the startup type will not affect the current status of the service.

PS C:\> set-service remoteregistry -StartupType Disabled -PassThru
Status Name DisplayName
------ ---- -----------
Running remoteregistry Remote Registry


So if you want to turn off and stop (or turn on and start) the service, pass the object to the appropriate cmdlet.

PS C:\> set-service remoteregistry -StartupType Disabled -PassThru | Stop-Service -PassThru
Status Name DisplayName
------ ---- -----------
Stopped remoteregistry Remote Registry


Technically, Set-Service allows you to change the display name of the service and description, but I personally have never had to use it in my work. I use Set-Service to enable and disable services. If you need to manage services remotely, then I use Invoke-Command .
All that I demonstrated in recent articles was related to the use of specific types of service objects, which, as you may have noticed, have some limitations. In the next article, we will look at other service management features that are designed to circumvent these limitations.

Upd:
The post contains translations of articles from the 4sysops.com portal .
Managing Services the PowerShell way - Part 3
Managing Services the PowerShell way - Part 4

Also popular now: