- Use PowerShell splatting and PSBoundParameters to pass parameters - Wed, Nov 9 2022
- Using PowerShell with $PSStyle - Mon, Jan 24 2022
- Clean up user profiles with PowerShell - Mon, Jun 9 2014
In the last article, I demonstrated some examples of using Set-Service to configure services. However there are some limitations, especially when working with services on remote machines. Part of the problem is that cmdlets like Get-Service and Set-Service are designed to work with a .NET Framework definition of a service object, System.ServiceProcess.ServiceController. From an IT Pro perspective there are a few things missing such as the account the service is running under. But fortunately we have Windows Management Instrumentation (WMI). We don’t have WMI-based cmdlets specific to services but this really isn’t that complicated.
Using WMI
We can use Get-WmiObject to retrieve an instance of a service object. I’m going to demonstrate using PowerShell 3.0 on Windows 8, but the same commands should work on PowerShell 2.0. It is not that difficult to retrieve all services, which are instances of the Win32_Service class.
PS C:\> get-wmiobject win32_service | format-table
Retrieve an instance of a service object with Get-WmiObject
As you can see in the screenshot above, I formatted the results as a table to make it easier to read. You get the same sort of information, although because this is a different object type, the property names might be different. Let’s look at a single service.
PS C:\> get-wmiobject win32_service -filter "name='bits'" ExitCode : 0 Name : BITS ProcessId : 876 StartMode : Auto State : Running Status : OK
This is merely the default display. There are other properties which you can see with a command like this:
PS C:\> get-wmiobject win32_service -filter "name='bits'" | Select *
The next screenshot displays the result.
Display Service properties
Once you know property names you can build some useful queries with the –Filter parameter.
Getting Startup Type
The StartMode property indicates whether a service is meant to auto start or manually start. Once you know this, you can run commands like this.
PS C:\> get-wmiobject win32_service -filter "StartMode <>'disabled'" | sort StartMode | format-table -GroupBy StartMode -Property Name,State,PathName -AutoSize
This will prepare a table, grouped by start mode with new key properties. I’ll let you run it on your own to see the results. Or perhaps you need to find all the services that are configured to auto start, but are currently not running.
PS C:\> get-wmiobject win32_service -filter "startmode='auto' AND state<>'Running'" | Select Name,State Name State ---- ----- MMCSS Stopped RemoteRegistry Stopped sppsvc Stopped wuauserv Stopped
I’m querying services locally, but it is just as easy to query one or more remote machines.
PS C:\> get-wmiobject win32_service -filter "startmode='auto' AND state<>'Running'" - computername chi-dc01,chi-dc02,chi-dc03 | Select Name,State,Systemname Name State Systemname ---- ----- ---------- sppsvc Stopped CHI-DC01 sppsvc Stopped CHI-DC02 VMTools Stopped CHI-DC02 RemoteRegistry Stopped CHI-DC03 ShellHWDetection Stopped CHI-DC03 sppsvc Stopped CHI-DC03 wuauserv Stopped CHI-DC03
Getting Service Account
The other piece of information that we can only retrieve with WMI is the account that the service is running under. In WMI, this is the Startname property.
PS C:\> get-wmiobject win32_service -comp chi-ex01 | group startname Count Name Group ----- ---- ----- 95 localSystem {\\CHI-EX01\root\cimv2:Win32_Service.Name="AeLook... 36 NT AUTHORITY\LocalService {\\CHI-EX01\root\cimv2:Win32_Service.Name="ALG", ... 24 NT AUTHORITY\NetworkSe... {\\CHI-EX01\root\cimv2:Win32_Service.Name="aspnet...
Of course you can filter on this property.
You can see the result in the screenshot below.
Getting Service account
This is very handy if you are searching for services running under a specific account, such as domain account.
PS C:\> get-wmiobject win32_service -computer $computers -filter "startname like '%administrator%'"| Select Name,startmode,state,startname,systemname Name : BITS startmode : Manual state : Stopped startname : .\Administrator systemname : CHI-EX01 Name : PeerDistSvc startmode : Manual state : Stopped startname : Administrator@GLOBOMANTICS.local systemname : CHI-WIN8-01
With one simple command I found services in that are running under some sort of administrator account, which may or may not be what I intend.
Using CIM
If PowerShell 3.0 is an option you can also use the CIM cmdlets to make the same types of queries. The advantage is that CIM uses PowerShell’s remoting port which makes it much more firewall friendly.
PS C:\> get-ciminstance win32_service -comp chi-dc01
Manage Services with CIM cmdlets
Filters work the same way.
PS C:\> get-ciminstance win32_service -filter "startmode='auto' AND state<>'Running'" -comp chi-ex01 | Select Name,State,Systemname Name State Systemname ---- ----- ---------- clr_optimization_v4.0.30319_32 Stopped CHI-EX01 clr_optimization_v4.0.30319_64 Stopped CHI-EX01 MSExchangeProtectedServiceHost Stopped CHI-EX01 MSExchangeRPC Stopped CHI-EX01 MSExchangeSA Stopped CHI-EX01 MSExchangeServiceHost Stopped CHI-EX01 ShellHWDetection Stopped CHI-EX01 sppsvc Stopped CHI-EX01
Looks I have some Exchange issues to look into. How do I accomplish that with WMI or CIM? That’s what we’ll look at in the next part.
Summary
Using WMI or CIM is a great way for reporting on service configuration in your environment. The Win32_Service class offers a bit more information that is of interest to IT Pros. Plus you can run long running queries with –Asjob or use alternate credentials. There are ways you could also do that with Get-Service but they require a little more work. Next time we’ll look at changing services with WMI and CIM.
How to stop all services configured through domain account in remote server
Stop-Service: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/stop-service?view=powershell-5.1