Windows Services are what make the operating system work. Services perform specific functions on each Windows computer. They update the system time, fetch and update the computer’s IP address, let users sign in to their profile, etc.
Services are one of the most essential parts of your computer’s operating system, and that’s not up for debate. But they sometimes stop unexpectedly or wouldn’t start at all. So, how do you know the status of the services?
The usual way is to open the Services MMC snap-in by running the services.msc command.
For hardcore, old-school users, the sc query command-line tool may be the more preferred way.
But we’re not talking about those tools in this article. Instead, we’ll explore the Get-Service PowerShell cmdlet, which combines the power of the sc query command and the convenience of the Services management console.
Table of Contents
Get-Service: Syntax and Parameters
First, let’s learn the syntax and parameters of the Get-Service cmdlet. There are three parameter sets to the Get-Service command.
The first parameter set has no required parameters but accepts the service name through the -Name parameter to identify which service to display.
Get-Service [[-Name] <string[]>] [-ComputerName <string[]>] [-DependentServices] [-RequiredServices] [-Include <string[]>] [-Exclude <string[]>] [<CommonParameters>]
The second one requires the -DisplayName parameter to identify the service to return. Every other parameter is optional.
Get-Service -DisplayName <string[]> [-ComputerName <string[]>] [-DependentServices] [-RequiredServices] [-Include <string[]>] [-Exclude <string[]>] [<CommonParameters>]
The last parameter set also has no required parameters but accepts one or more service controller objects through the -InputObject parameter.
Get-Service [-ComputerName <string[]>] [-DependentServices] [-RequiredServices] [-Include <string[]>] [-Exclude <string[]>] [-InputObject <ServiceController[]>] [<CommonParameters>]
Get-Service: Service Object Properties
The Get-Service cmdlet returns a default property set consisting of the following properties:
- Status — Indicates the current service status. The possible status values are: Stopped, StartPending, StopPending, Running, ContinuePending, PausePending, Paused.
- Name — Displays the short name of the service. This property is an alias of the ServiceName property.
- Display Name — Display the friendly name of the service.
However, more service object properties are not displayed. You can see them by running the below command.
Get-Service | Get-Member | Where-Object { $_.MemberType -like "*property" } | Select-Object Name, MemberType
Among these other properties, the most preferred when checking the service status is the StartType, which indicates whether the service start type is:
- Automatic — Service starts automatically during the system start-up.
- Manual — Service must be started manually by a user or application.
- AutomaticDelayedStart — Service starts after the system boots.
- Disabled — Service is disabled.
Refer to Microsoft’s ServiceController Class documentation for the comprehensive list of properties.
Get-Service: Basic Usage
The most basic usage of the Get-Service cmdlet is to run it without parameters. Doing so will return all services on the local computer.
Get-Service
Next, specify the service name you want to retrieve using the -Name parameter.
Get-Service -Name WinRM
An alternative is to specify the service display name through the -DisplayName parameter.
Get-Service -DisplayName 'Windows Remote Management (WS-Management)'
But because the -Name and -DisplayName parameters are ordinally the first parameters in their respective parameter sets, you can omit them and directly enter the service name or display name after the Get-Service cmdlet. The result will be the same either way.
Get-Service WinRM Get-Service 'Windows Remote Management (WS-Management)'
Note that the -DisplayName and -Name parameter accepts an array. You can specify multiple service names and display names or a mix of both at once.
For example, the below command retrieves two services by their DisplayName and Name.
Get-Service 'Windows Management Instrumentation',WinRM
The -Name and -DisplayName parameters also accept wildcard characters. For example, the command below lists all services whose name starts with E.
Get-Service -Name E*
The following command lists all services whose display name starts with Microsoft.
Get-Service -DisplayName Microsoft*
Get-Service: Advanced Usage Examples
Now we move to what you came here for—using the Get-Service cmdlet to check service status.
Checking the Services on a Remote Computer
The Get-Service cmdlet retrieves the service status in the local computer by default. But it is capable of getting the service status on a remote computer.
On Windows PowerShell, the Get-Service cmdlet has a parameter called -ComputerName that accepts an array of computer names to query. This method uses the Distributed Component Object Model (DCOM) to connect to the remote machine and execute the command against it.
For example, this command retrieves the status of the services on the remote computers named DC1 and PCX.
Get-Service -Name WinRM -ComputerName DC1,PCX | Select-Object Status,Name,MachineName
On PowerShell Core (6.x+), the -ComputerName parameter has been removed from the Get-Service cmdlet because of PowerShell Core’s move away from DCOM. Instead, you must use the Invoke-Command cmdlet, which uses the WinRM to communicate to remote machines.
The WinRM service must be running on the remote computer for this to work.
Invoke-Command -ComputerName DC1, PCX {Get-Service WinDefend, wuauserv | Select-Object Status, Name, DisplayName}
Checking the Status of Automatic Services
The nature of automatic services is that they should be running, especially on servers. If an automatic service is not running, administrators must be able to see their status so they can act on it.
In this example, we’ll get all services whose StartType is Automatic.
Get-Service | Where-Object { $_.StartType -eq 'Automatic' } | Select-Object Name, Status, StartType
Listing Not Running Automatic Services
In the previous example, we listed all automatic services and their status. Knowing whether the automatic service is running does not have value in the context of monitoring. The better option is to show only the automatic services that are not running so you can spot them quickly.
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' } | Select-Object Status, Name, DisplayName, StartType
Listing Not Running Automatic Services with Exclusions
Just because the service’s start type is automatic, it doesn’t mean that it has to be constantly running. Some services start automatically on system start-up and can stop automatically when they have nothing to do.
In such cases, you can add exclusions like the edgeupdate and sppsvc in the previous example. The example below creates an array of service names to exclude from the result. The next command filters the result to exclude the services whose names are in the $exclude array.
$exclude = @('edgeupdate','sppsvc') Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' -and $_.Name -notin $exclude } | Select-Object Status, Name, DisplayName, StartType
Another way is to use the -Exclude parameter.
$exclude = @('edgeupdate','sppsvc') Get-Service -Exclude $exclude | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' } | Select-Object Status, Name, DisplayName, StartType
Checking the Status of Service Dependencies
Some services depend on other services for them to run. These services may fail to start if their required services are not running.
For example, let’s check the required services of the Dfs service.
Get-Service Dfs -RequiredServices
According to the result below, the Dfs service has six dependencies, and one is not running (Stopped), which is the RemoteRegistry.
In this case, the administrator can start the required service by running Start-Service RemoteRegistry.
Script to Check the Status of Service Dependencies
Here’s a sample script that checks the status of the services and their required services. Copy the code below and save it as Get-ServiceDependecyStatus.ps1.
You can also download this script from this Gist.
# Get-ServiceDependecyStatus.ps1 [CmdletBinding()] param ( [Parameter(Mandatory)] [System.Object[]] $ServiceList ) foreach ($currentService in $ServiceList) { try { if (($currentService | Get-Member).TypeName -eq 'System.String') { $service = Get-Service $currentService -ErrorAction Stop } if (($currentService | Get-Member).TypeName -like "*ServiceController*") { $service = $currentService } } catch { continue } # Return the result [PSCustomObject]@{ Name = $service.Name Status = $service.Status StartType = $service.StartType RequiredServicesNotRunning = @(($service.RequiredServices | Where-Object { $_.Status -ne 'Running' }).Name) -join ";" RequiredServicesRunning = @(($service.RequiredServices | Where-Object { $_.Status -eq 'Running' }).Name) -join ";" } }
Once you’ve saved it, open PowerShell and change the working directory to where you saved the script.
CD <path_to_script>
Related post. Navigating the Filesystem with PowerShell Change Directory Commands
Run the script to check the required service status of one or more services. I’m checking the WinDefend, wuauserv, dfs, and WinRM services in this example.
.\Get-ServiceDependecyStatus.ps1 -ServiceList WinDefend,wuauserv,dfs,winrm
As you can see below, the result shows the required services that are running and not running.
What if you want to check all services? Here’s how.
.\Get-ServiceDependecyStatus.ps1 -ServiceList (Get-Service)
Conclusion
Regularly checking the status of Windows services is crucial to maintaining a well-functioning system. This task is made convenient using the PowerShell Get-Service cmdlet. Whether running the cmdlet interactively or in a script, the information it produces is valuable for proactive remediation.
1 comment
‘(Get-Service -Name wuauserv).StartupType’ is wrong to identify if “disabled”
Like this:
if((Get-Service -computername $server -Name “ArcGIS Server”).StartType -ieq “disabled”){continue}