Working with Windows Services in PowerShell

by Adam Bertram Posted on July 05, 2017

EFT-and-cloud-survey-finding.jpg

PowerShell helps free up time by taking over certain service management tasks. See how to create such tools here. 

 

Stopping, starting, and restarting Windows services is a common task for many IT professionals. We're all used to the common services MMC snapin where we browse to a service, right-click on the service, restart it or double-click on it and change various attributes of a service. If we're saving some time, we might even connect to a remote computer in the services snapin and manage them that way, but this method of working with Windows services soon becomes a pain.

It gets old, and wastes an IT pro's valuable time, clicking around in a GUI when managing lots of services! Luckily, by using PowerShell, we can build tools to perform a lot of these service management tasks for us.

 

PowerShell gives us some commands right out of the box to work with Windows services.

PS> Get-Command -Noun Service

CommandType Name            Version Source
----------- ----            ------- ------
Cmdlet      Get-Service     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      New-Service     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Restart-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Resume-Service  3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Set-Service     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Start-Service   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Stop-Service    3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Suspend-Service 3.1.0.0 Microsoft.PowerShell.Management

Taking a Look with Get-Service

We can leverage these built-in commands to perform all kinds of tasks to make our service management lives easier. For example, perhaps I'd like to somehow get the service status of lots of different computers at once from Active Directory. To create such a tool, I could leverage the Active Directory PowerShell module, pull the computers from AD, and then feed those computer names to the Get-Service command.

Read: Using The PowerShell Test-NetConnection Cmdlet On Windows

$computers = Get-AdComputer -Filter * | Select-Object -ExpandProperty Name
get-service -ComputerName $computers -Name wuauserv | Select-Object MachineName,Name,Status

MachineName Name      Status
----------- ----      ------
DC          wuauserv Running
CLIENT1     wuauserv Running
...

Now maybe I'd like to restart all of the services on all of those computers at once. To do that, I can pipe the results I just got directly to Restart-Service.

Get-Service -ComputerName $computers -Name wuauserv | Restart-Service

We could use the same approach for starting services or stopping services as well. Instead of using Restart-Service, I could have just as easily as used Stop-Service or Start-Service.

Changing Things with Set-Service

Services can also be modified using the Set-Service command. With the Set-Service command, I can do things like change a service's display name, startup type or description. Again, using the services we obtained with Get-Service earlier, I can pipe those services to the Set-Service command to perform some different actions.

## Change the display name for all wuauserv services to 'foo'
Get-Service -ComputerName $computers -Name wuauserv | Set-Service -DisplayName 'foo'

## Change the description to 'stuff'
Get-Service -ComputerName $computers -Name wuauserv | Set-Service -Description 'stuff'

Changing Service Credentials

You can see that as soon as you can query the services using Get-Service, just about anything can be done to those services. However, not everything can be done with the built-in commands. For instance, it's not possible to change the username and password a service runs under using a Service command. Instead, we need to create our own method using WMI. To change service credentials, we'll have to pull the service directly from WMI and invoke a .NET method on it to modify the service account. Here's an excellent example of how to do that.

## Gather the username and password
$credential = Get-Credential

## Find the service to change
$params = @{
  'Namespace' = 'root\CIMV2'
  'Class' = 'Win32_Service'
  'Filter' = "DisplayName='App Service'"
}
$service = Get-WmiObject @params

## Make the change using the username and password
$service.Change($null,
  $null,
  $null,
  $null,
  $null,
  $null,
  $credential.UserName,
  $credential.GetNetworkCredential().Password,
  $null,
  $null,
  $null
)

Even though everything's not possible using the built-in service cmdlets, since PowerShell is built on top of .NET, just about anything is possible if you know where to look!

 

Adam Bertram

Adam Bertram is a 25+ year IT veteran and an experienced online business professional. He’s a successful blogger, consultant, 6x Microsoft MVP, trainer, published author and freelance writer for dozens of publications. For how-to tech tutorials, catch up with Adam at adamtheautomator.com, connect on LinkedIn or follow him on X at @adbertram.

More from the author

Related Articles

How to Search Windows Event Logs Across Hundreds of Servers
The Windows event logs are a great place to start when troubleshooting problems or investigating potential security breaches.
Using the New MOVEit 2018 REST API with PowerShell
Logging into MOVEit's console or web interface works great for day-to-day management tasks or setting up one-time workflows but there are times when we need to automate with MOVEit Automation!
Creating New Users in MOVEit Transfer 2018 with PowerShell
In the previous articles, we focused on MOVEit Automation's REST API, but it’s now time to focus on MOVEit Transfer.
Prefooter Dots
Subscribe Icon

Latest Stories in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation