📜 ⬆️ ⬇️

Manage Windows Services with PowerShell


We are starting a series of translations dedicated to managing Windows services using PowerShell 2.0 and 3.0.
This post will cover the following issues for managing Windows services:


Let's designate initial conditions: you work under Windows 7 and above and you have administrator rights. All commands are recommended to be performed in a laboratory or virtual environment, before being applied in “field conditions”.

GET THE SERVICE STATUS



Let's start by simply getting the status of all services running on the local computer. Use the Get-Service cmdlet for this.
')
PS C:\> get-service 


PowerShell is generally not case sensitive. The output is shown in the screenshot below.



Each line is a service object. Each service object usually has its own properties. You can open them by simply passing these objects to another command, Get-Member .

 PS C:\> get-service | get-member 


The results are shown in the screenshot below.



The parameter Typename above indicates that the object is in front of us; in this case, System.ServiceProcess.ServiceController. The screenshot also outlines the properties of the object. These are the attributes that describe this type of object. Although most of them are not used when displaying by default, you can use them if you know them.
For example, we are interested to see information only about Windows Update. Through Get-Service we will receive information only about some of its properties.

 PS C:\> get-service wuauserv | select Displayname,Status,Can* DisplayName : Windows Update Status : Stopped CanPauseAndContinue : False CanShutdown : False CanStop : False 
How do I know that I can type the name of the service? Looked using Get-Service.
PS C: \> help get-service



You can get complete background information by typing:

 PS C:\> help get-service –full 


Information about the service can be obtained by its name or even the initial letters of the name.

 PS C:\> get-service wi* Status Name DisplayName ------ ---- ----------- Stopped WiaRpc Still Image Acquisition Events Running WinDefend Windows Defender Service Running WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se... Running Winmgmt Windows Management Instrumentation Running WinRM Windows Remote Management (WS-Manag... 


Or if you prefer to work with display names, use the –Displayname parameter.

 PS C:\> get-service -DisplayName "windows a*" Status Name DisplayName ------ ---- ----------- Stopped AllUserInstallA... Windows All-User Install Agent Running AudioEndpointBu... Windows Audio Endpoint Builder Running Audiosrv Windows Audio 


I have to use the parameter name for PowerShell to take the values ​​as the display name, not the actual service name. The command will look like this:

 PS C:\> get-service "windows a*" 


The parameter –Name can not be printed.

WE GET THE SERVICE STATUS ON REMOTE COMPUTERS



Prior to this, we were interested in obtaining information about the status of services on the local computer. However, services are managed on remote computers. If you look at the Get-Service help, you can see that the cmdlet has the –Computername parameter. In this case, connecting to remote computers is done without enabling PowerShell remote control. If you can manage services using the command line tools (sc.exe or Service Manager Management Console), you can use PowerShell. Let's take a look at an example:

 PS C:\> get-service spooler -ComputerName novo8 Status Name DisplayName ------ ---- ----------- Running spooler Print Spooler 


Any command I have demonstrated can be used to transfer to a remote computer. Even multiple computers, if you have the appropriate rights on a remote computer. If you are using PowerShell v3, you can easily select one service on multiple computers.

 PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03 Status Name DisplayName ------ ---- ----------- Running wuauserv Windows Update Stopped wuauserv Windows Update Running wuauserv Windows Update 


For clarity, the presentation format the output.

 PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03 | format-table Name,Status,Machinename -autosize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc03 wuauserv Stopped chi-dc02 wuauserv Running chi-dc01 


The same result, but in PowerShell v2.

 PS C:\> 'chi-dc01','chi-dc02','chi-dc03'| foreach {get-service wuauserv -computername $_} | Format-Table Name,Status,Machinename -AutoSize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc01 wuauserv Stopped chi-dc02 wuauserv Running chi-dc03 


WE PERFORM FILTRATION (USING WHERE-OBJECT)



Services are filtered using the Where-Object cmdlet (where is the abbreviation for the cmdlet). All we need from PowerShell in this case is to get only those services that have “stopped” status.

 PS C:\> get-service | where {$_.status -eq 'stopped'} 


PowerShell receives information about all services and sends them (using “|”) to the next command, which scans each object. If the status property of an object is “stopped”, it remains in the pipeline, otherwise it is excluded from it. At the end, the PowerShell expression displays the objects that remain in the pipeline.
The results are shown below.



Now let's try to find one service on several machines. The output is formatted into a table.

 PS C:\> get-service -computername @('chi-dc01','chi-dc02','chi-dc03') | where {$_.name -eq 'wuauserv'} | format-table Name,Status,Machinename -autosize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc02 wuauserv Running chi-dc01 wuauserv Running chi-dc03 


We can even combine the request of individual services with their filtering.

 PS C:\> get-service "win*" -comp chi-dc03 | where {$_.status -eq 'running'} Status Name DisplayName ------ ---- ----------- Running Winmgmt Windows Management Instrumentation Running WinRM Windows Remote Management (WS-Manag... 


This command finds all the services on the CHI-DC03 computer that start with 'WIN', but displays only those that are running.
You can also group objects by status status (status property).

 PS C:\> $dc03 = get-service -computername chi-dc03 | Group-Object -Property Status 


The variable $ dc03 is a GroupInfo object.

 PS C:\> $dc03 Count Name Group ----- ---- ----- 64 Running {System.ServiceProcess.ServiceController, Sy... 79 Stopped {System.ServiceProcess.ServiceController, Sy... 


The Group property is a collection of related services.

 PS C:\> $dc03.Get(0).group 


The above is easier to understand if you look at the screenshot.



As for me, I would prefer to use a hash table.

 PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status -AsHashTable PS C:\> $hash Name Value ---- ----- Running {System.ServiceProcess.ServiceController, Sys... Stopped {System.ServiceProcess.ServiceController, Sys... 


Now each name is a property in the hash table. If you have experience with PoweShell, you might be thinking of doing the following:

 PS C:\> $hash.running.count 


However, nothing will happen. Because the Status property is just an enumeration for [System.ServiceProcess.ServiceControllerStatus] .NET class and properties such as Running and Stopped are integers. PowerShell performs the conversion to present in a more visual form.

 PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status –AsHashTable –AsString 


What is the essence of the –AsString parameter, in my opinion, is quite obvious. Now it’s easier to work with the hash table.

 PS C:\> $hash.running.count 62 PS C:\> $hash.running[0..3] Status Name DisplayName ------ ---- ----------- Running ADWS Active Directory Web Services Running AppHostSvc Application Host Helper Service Running BFE Base Filtering Engine Running BrokerInfrastru... Background Tasks Infrastructure Ser... 


The next task on the agenda is to check server dependencies (server dependencies).

Required Services


PowerShell allows you to simply get the status of all services that are required for a given service, even on a remote computer.

 PS C:\> get-service dns -ComputerName chi-dc03 –RequiredServices Status Name DisplayName ------ ---- ----------- Running Afd Ancillary Function Driver for Winsock Running Tcpip TCP/IP Protocol Driver Running RpcSs Remote Procedure Call (RPC) Running NTDS Active Directory Domain Services 


The –RequiredServices parameter will pass an object to the pipeline for each required service. You can even go ahead and check the required services for this service to work.

 PS C:\> get-service dns -ComputerName chi-dc03 -RequiredServices | select name,@{name="computername";expression={$_.machinename}} | get-service -RequiredServices Status Name DisplayName ------ ---- ----------- Running RpcEptMapper RPC Endpoint Mapper Running DcomLaunch DCOM Server Process Launcher 


The –Computername parameter of the Get-Service cmdlet will take output, but only for those objects that have an object property Computername - which is why I use a hash table with Select-Object. As we can see, there are no problems with the DNS service on the CHI-DC03 computer.

DEPENDENT SERVICES



We can do the same with dependent services. If there are none, nothing will be transferred to the conveyor.

 PS C:\> get-service dns -ComputerName chi-dc03 -DependentServices PS C:\> get-service lanmanworkstation -ComputerName chi-dc03 -DependentServices Status Name DisplayName ------ ---- ----------- Stopped SessionEnv Remote Desktop Configuration Running Netlogon Netlogon Running Dfs DFS Namespace Running Browser Computer Browser 


Required and dependent services are also part of each service object.

 PS C:\> get-service rpcss | Select *services RequiredServices DependentServices ---------------- ----------------- {RpcEptMapper, DcomLaunch} {WwanSvc, wuauserv, WSearch, wscsvc...} 


In the meantime, you can get all the dependencies for all services, the following command

 PS C:\> get-service –DependentServices 


This will not give you particularly useful information, so I recommend making a request for specific services. The team works much better than PowerShell v3.

 PS C:\> get-service dns -comp chi-dc01,chi-dc03 -RequiredServices | Sort Machinename,Name | Format-table -GroupBy machinename 


The results are visible in the screenshot below.



To get similar results in PowerShell v2, you will have to pass the computer names (computernames) to Get-Service.
 PS C:\> "chi-dc01","chi-dc03" | foreach { get-service dns -comp $_ -RequiredServices} | Sort Machinename,Name | format-table -GroupBy machinename 


The following article will discuss starting, stopping and restarting services.
The end of the translation.

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

PS We also want to share our free program for managing Windows services - NetWrix Service Monitor . The program keeps track of all automatically started services on a group of servers and in case of a sudden failure of one or several of them sends email notifications. The restart function ensures that all control services will work without downtime. The program is easy to configure: install, enter the names of computers and specify the desired email address.

Source: https://habr.com/ru/post/166289/


All Articles