Skip to content

Services Management

Note

Query, start, stop, and configure Windows services with Get-Service, Start-Service, Stop-Service, and Restart-Service.

Overview

Windows services run in the background — think print spoolers, SQL Server instances, or your own scheduled agents. PowerShell's service cmdlets let you check status, control state, and inspect dependencies without opening services.msc. They're some of the most direct, no-surprises cmdlets in the whole language: Get-Service reads, Start/Stop/Restart-Service act.

Basic Syntax

Get-Service -Name "Spooler"
Start-Service -Name "Spooler"
Stop-Service -Name "Spooler"
Restart-Service -Name "Spooler"
Set-Service -Name "Spooler" -StartupType Automatic

Key Points

  • Get-Service works on both the short service name (wuauserv) and display name (Windows Update)
  • -Name accepts wildcards: Get-Service -Name "sql*"
  • Stopping a service with dependents fails unless you pass -Force
  • Managing services on Windows requires an elevated (Administrator) PowerShell session

Querying Services

# All services
Get-Service

# Single service by name
Get-Service -Name "Spooler"

# Wildcard search
Get-Service -Name "sql*"

# Only running services
Get-Service | Where-Object { $_.Status -eq "Running" }

# Only stopped services that are set to auto-start (a common problem indicator)
Get-Service | Where-Object { $_.Status -eq "Stopped" -and $_.StartType -eq "Automatic" }

Output:

Status   Name               DisplayName
------   ----               -----------
Running  Spooler            Print Spooler
Stopped  wuauserv           Windows Update
Running  W32Time            Windows Time

Service Details

# Full property list, not just the default table
Get-Service -Name "Spooler" | Format-List *

# Startup type
Get-Service -Name "Spooler" | Select-Object Name, Status, StartType

# Service dependencies
$service = Get-Service -Name "Spooler"
$service.DependentServices        # services that depend on this one
$service.ServicesDependedOn       # services this one depends on

Starting, Stopping, and Restarting

# Start a stopped service
Start-Service -Name "Spooler"

# Stop a running service
Stop-Service -Name "Spooler"

# Stop a service even if other services depend on it
Stop-Service -Name "Spooler" -Force

# Restart (stop then start) in one call
Restart-Service -Name "Spooler"

# Preview before acting
Stop-Service -Name "Spooler" -WhatIf

Stopping a Service With Dependents

# BAD - fails if other services depend on this one
Stop-Service -Name "RpcSs"
# Error: Cannot stop service because other services depend on it

# GOOD - stop dependents too (use with caution)
Stop-Service -Name "RpcSs" -Force
-Force cascades the stop to every dependent service. Check DependentServices first so you know what else is about to go down.

Bulk Operations

# Restart every service matching a pattern
Get-Service -Name "MSSQL*" | Restart-Service -Force

# Stop all services in a specific list
$servicesToStop = @("Spooler", "Fax", "WSearch")
Get-Service -Name $servicesToStop | Stop-Service -Force

# Report on a group of critical services
$criticalServices = @("Spooler", "WinRM", "W32Time")
Get-Service -Name $criticalServices | Select-Object Name, Status, StartType |
    Format-Table -AutoSize

Configuring Startup Type

# Change startup type
Set-Service -Name "Spooler" -StartupType Automatic
Set-Service -Name "Fax" -StartupType Disabled
Set-Service -Name "WSearch" -StartupType Manual

# Change startup type and start it in the same operation
Set-Service -Name "Spooler" -StartupType Automatic -Status Running

StartupType Values

Automatic starts at boot. AutomaticDelayedStart (Windows Server / newer Windows) starts shortly after boot to reduce startup contention. Manual only starts when explicitly triggered or requested by another service. Disabled prevents it from starting at all, even manually, until re-enabled.

Remote Service Management

# Query a service on a remote computer
Get-Service -Name "Spooler" -ComputerName "SERVER01"

# Query across multiple computers
$computers = @("SERVER01", "SERVER02", "SERVER03")
Get-Service -Name "Spooler" -ComputerName $computers |
    Select-Object MachineName, Name, Status

# Restart a service remotely with Invoke-Command (works even where -ComputerName is deprecated)
Invoke-Command -ComputerName "SERVER01" -ScriptBlock {
    Restart-Service -Name "Spooler" -Force
}

Get-Service -ComputerName Is Being Phased Out

-ComputerName on Get-Service/Stop-Service/etc. only supports read/simple operations remotely and isn't available in all PowerShell 7+ contexts. For reliable remote control — especially anything that changes state — use Invoke-Command with PowerShell Remoting instead.

Important Parameters

Parameter Type Description Example
-Name String[] Service name(s), supports wildcards Get-Service -Name "sql*"
-DisplayName String Filter by the friendly display name Get-Service -DisplayName "Print*"
-Force Switch Stop dependent services too Stop-Service -Force
-StartupType String Automatic, Manual, Disabled Set-Service -StartupType Manual
-Status String Set-Service: desired running state Set-Service -Status Running
-ComputerName String[] Query a remote machine (read-focused) Get-Service -ComputerName "S1"
-WhatIf Switch Preview the action Stop-Service -WhatIf

Common Patterns

# Pattern 1: Restart a service only if it's currently running
$svc = Get-Service -Name "Spooler"
if ($svc.Status -eq "Running") {
    Restart-Service -Name "Spooler" -Force
}

# Pattern 2: Ensure a service is running and set to auto-start
$serviceName = "WinRM"
Set-Service -Name $serviceName -StartupType Automatic
if ((Get-Service -Name $serviceName).Status -ne "Running") {
    Start-Service -Name $serviceName
}

# Pattern 3: Health check across a list of critical services
$critical = @("Spooler", "WinRM", "W32Time", "Dnscache")
Get-Service -Name $critical | ForEach-Object {
    [PSCustomObject]@{
        Service = $_.Name
        Status  = $_.Status
        Healthy = ($_.Status -eq "Running")
    }
}

Real-World Examples

Example: Service Health Check with Auto-Remediation

Scenario: Check a list of services that should always be running; restart any that have stopped and log what happened.

$requiredServices = @("Spooler", "WinRM", "W32Time")
$logPath = "C:\Logs\service-check.log"

foreach ($name in $requiredServices) {
    $service = Get-Service -Name $name -ErrorAction SilentlyContinue

    if (-not $service) {
        Add-Content -Path $logPath -Value "$(Get-Date) - $name not found on this system"
        continue
    }

    if ($service.Status -ne "Running") {
        Add-Content -Path $logPath -Value "$(Get-Date) - $name was $($service.Status), restarting"
        Start-Service -Name $name
    }
}

Explanation: -ErrorAction SilentlyContinue handles services that don't exist on a given machine gracefully, and the log gives a clear audit trail of exactly what got restarted and when.

Tips & Tricks

Check DependentServices Before Stopping Anything

$service = Get-Service -Name "RpcSs"
$service.DependentServices | Select-Object Name, Status
Reviewing what depends on a service before stopping it avoids the surprise of taking down half the OS because of one careless -Force.

Service Names vs Display Names

# This works - short service name
Get-Service -Name "wuauserv"

# This does NOT work with -Name - that's the display name
Get-Service -Name "Windows Update"   # fails, no match

# Use -DisplayName for the friendly name instead
Get-Service -DisplayName "Windows Update"
-Name matches the internal short name; -DisplayName matches what you see in services.msc. Mixing them up is a common source of "service not found" errors.

Additional Resources