Managing Services from PowerShell

PowerShell’s service cmdlets wrap the Service Control Manager (for the underlying architecture — why services must answer the SCM handshake, where config lives in the registry, and how services get exploited — see windows-services):

Get-Service                          # list all services and their status
Get-Service -Name Spooler            # one service
Get-Service | Where-Object Status -eq Running
Start-Service -Name Spooler
Stop-Service -Name Spooler
Restart-Service -Name Spooler
Set-Service -Name Spooler -StartupType Disabled
New-Service -Name evil -BinaryPathName "C:\evil.exe"   # service creation

Notes:

  • Get-Service returns ServiceController objects with Status, StartType (PS 6+), and Name/DisplayName — both names work as -Name input, which trips people up (Get-Service "Print Spooler"Get-Service Spooler).
  • New-Service exists since PowerShell 6.0; on Windows PowerShell 5.1 you fall back to sc.exe create or WMI (Win32_Service.Create).
  • -ComputerName parameters were removed in PowerShell 6 — remote management goes through CIM/WMI (Get-CimInstance Win32_Service) or sc.exe \\host.

The sc.exe alternative (and the alias trap)

sc.exe predates PowerShell and exposes everything the cmdlets do plus config queries (sc.exe qc), DACL work (sc.exe sdshow/sdset), and remote targeting (sc.exe \\host ...):

sc.exe query            # all services with state
sc.exe start Spooler
sc.exe stop Spooler
sc.exe qc Spooler       # config: binary path, start type, account

Trap: in PowerShell, sc is the alias for Set-Content. Typing sc start Spooler in PowerShell writes a file named start containing “Spooler”. Always use the explicit sc.exe inside PowerShell. The same trap applies when exploiting service misconfigurations via one-liners.

Recon quick hits

Get-Service | Where-Object {$_.Status -eq 'Running'}     # T1007 System Service Discovery
sc.exe query | findstr "SERVICE_NAME STATE"              # the classic
Get-CimInstance Win32_Service | Select Name,PathName,StartName,State

The CIM variant is the privesc goldmine — it exposes PathName (find writable binaries/unquoted paths — see exploit-windows-services-unquoted-paths) and StartName (services running as privileged accounts).

Sources