You are on page 1of 14

Deployment 

aaa1234

Managing Services the PowerShell way - Part 2: Filtering


Home / Blog / Managing Services the PowerShell way - Part 2: Filtering 4sy sops - The online communit y for Sy sAdmins and Dev Ops

Jeffery Hicks Thu, Jan 17 2013 powershell 5 

In the previous article we started exploring how to use PowerShell to manage Services . We used
the Get-Service command to retrieve service objects not only locally, but from remote computers
as well. We saw how to get services by name or display name. But what if you want to nd services
that are not running?

About Latest Posts

Jeffery Hicks
Je ery Hicks is a multi-year Microsoft MVP in Windows PowerShell, Microsoft Certi ed Professional and an
IT veteran with 25 years of experience specializing in automation. He works today as an author, trainer
and consultant.

Contents of this article

Filtering with Where-Object


Required Services
Dependent Services

Filtering with Where-Object ^

For that we turn to ltering using the Where-Object cmdlet. This command has an alias or shortcut of where.
All we need to do is tell PowerShell to get the services and only keep those where the status property is equal
to stopped.

PS C:\> get-service | where {$_.status -eq 'stopped'}

The $_ is a placeholder for the current service object in the pipeline. Or to put it in plainer language,
PowerShell got all the services and piped them (|) to the next command which looked at each object. If the
status property of the incoming object is equal to ‘stopped’, it remains in the pipeline, otherwise it is
discarded. At the end of the expression PowerShell displays whatever objects are left in the pipeline.

You can see the results in the screenshot.


Filtering with Where-Object

This same command will work in v2 or v3. PowerShell 3.0 actually has a simpli ed syntax for an expression like
this but I’ll skip it as if you are new to PowerShell I think you’ll be even more confused by it.

In the last part I showed how to query a single service on multiple machines. Here’s an alternative that uses
filtering.

1 PS C:\> get-service -computername @('chi-dc01','chi-dc02','chi-dc03') |


2 where {$_.name -eq 'wuauserv'} | format-table Name,Status,Machinename -autosize
3
4 Name Status MachineName
5 ---- ------ -----------
6 wuauserv Running chi-dc02
7 wuauserv Running chi-dc01
8 wuauserv Running chi-dc03

We can even combine getting specific services with filtering.

1 PS C:\> get-service "win*" -comp chi-dc03 | where {$_.status -eq 'running'}


2 Status Name DisplayName
3 ------ ---- -----------
4 Running Winmgmt Management Instrumentation
5 Running WinRM Windows Remote Management (WS-Manag ...

This command retrieved all the services on CHI-DC03 that started with ‘WIN’ but only kept those that are
running.
Another approach you can take is to group the objects based on their status property.

PS C:\> $dc03 = get-service -computername chi-dc03 | Group-Object -Property

Status

The variable $dc03 is a GroupInfo object.


1 PS C:\> $dc03
2
3 Count Name Group
4 ----- ---- -----
5 64 Running {System.ServiceProcess.ServiceController, Sy...
6 79 Stopped {System.ServiceProcess.ServiceController, Sy...

The Group property is a collection of the corresponding services.

PS C:\> $dc03.Get(0).group

This is easier to understand by looking at the following screenshot.

Filtering with Group-Object

Personally, I would prefer to use a hash table.

1 PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status


2 -AsHashTable
3
4 PS C:\> $hash
5 Name Value
6 ---- -----
7 Running {System.ServiceProcess.ServiceController, Sys...
8 Stopped {System.ServiceProcess.ServiceController, Sys...

Now, each name is a property of the hash table object. If you have some PowerShell experience you would
think you could do this:

PS C:\> $hash.running.count

But nothing will happen. This is because the Status property is actually an enumeration of the
[System.ServiceProcess.ServiceControllerStatus] .NET class and properties like Running and Stopped are
actually integers. PowerShell does some conversion behind the scenes to make it easier to understand. We
can still create a hash table, we just need to be clever about it.

PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property


Status –AsHashTable –AsString

The –AsString parameter does exactly what the name implies. Now, this is much easier to work with as a hash
table.
1 PS C:\> $hash.running.count
2 62
3 PS C:\> $hash.running[0..3]
4
5 Status Name DisplayName
6 ------ ---- -----------
7 Running ADWS Active Directory Web Services
8 Running AppHostSvc Application Host Helper Service
9 Running BFE Base Filtering Engine
10 Running BrokerInfrastru... Background Tasks Infrastructure Ser...

Next on our service management task list is checking server dependencies.

Required Services ^

PowerShell makes it very easy to display the status of all the services that are required for a given service, even
on a remote computer.

1 PS C:\> get-service dns -ComputerName chi-dc03 –RequiredServices


2
3 Status Name DisplayName
4 ------ ---- -----------
5 Running Afd Ancillary Function Driver for Winsock
6 Running Tcpip TCP/IP Protocol Driver
7 Running RpcSs Remote Procedure Call (RPC)
8 Running NTDS Active Directory Domain Services

The –RequiredServices parameter will write objects to the pipeline for every required service. You could even
take this a step further and check these services’ required services.

1 PS C:\> get-service dns -ComputerName chi-dc03 -RequiredServices | select


2 name,@{name="computername";expression={$_.machinename}} | get-service
3 -RequiredServices
4
5 Status Name DisplayName
6 ------ ---- -----------
7 Running RpcEptMapper RPC Endpoint Mapper
8 Running DcomLaunch DCOM Server Process Launcher

The Get-Service cmdlet’s –Computername parameter will take pipelined input but the incoming object must
have a Computername property which is why I used the hash table with Select-Object. But it looks like
everything is fine with the DNS service on CHI-DC03.

Dependent Services ^

We can do the same thing with dependent services. That is, services that depend on this service. If there are
none, you’ll get nothing written to the pipeline.

1 PS C:\> get-service dns -ComputerName chi-dc03 -DependentServices


2 PS C:\> get-service lanmanworkstation -ComputerName chi-dc03 -DependentServices
3
4 Status Name DisplayName
5 ------ ---- -----------
6 Stopped SessionEnv Remote Desktop Configuration
7 Running Netlogon Netlogon
8 Running Dfs DFS Namespace
9 Running Browser Computer Browser
Required and dependent services are also part of every service object.

1 PS C:\> get-service rpcss | Select *services


2
3 RequiredServices DependentServices
4 ---------------- -----------------
5 {RpcEptMapper, DcomLaunch} {WwanSvc, wuauserv, WSearch, wscsvc...}

And while you could get all dependencies for all services, a command like this

PS C:\> get-service –DependentServices

Doesn’t really tell you much so I recommend sticking with querying speci c services. Although you could query
the same service on multiple computers. This command works much better in PowerShell v3.

PS C:\> get-service dns -comp chi-dc01,chi-dc03 -RequiredServices | Sort


Machinename,Name | Format-table -GroupBy machinename

You can see the results in the next screenshot.

Dependent Services

To get similar results in PowerShell v2 you’ll need to pipe the computernames to Get-Service.

PS C:\> "chi-dc01","chi-dc03" | foreach { get-service dns -comp $_ -


RequiredServices} | Sort Machinename,Name | format-table -GroupBy machinename

In the next article we’ll look at starting, stopping and restarting services.

Join the 4sysops PowerShell group!

Articles in series

PowerShell and Services

1. Managing Services the PowerShell way - Part 1: Get Service status

2. Managing Services the PowerShell way - Part 2: Filtering

3. Managing Services the PowerShell way - Part 3: Start and stop Services

4. Managing Services the PowerShell way - Part 4: Configure Services

5. Managing Services the PowerShell way - Part 5: WMI and CIM


6. Managing Services the PowerShell way - Part 6: Modify through WMI

7. Managing Services the PowerShell way - Part 7: Stop and start with CIM

8. Managing Services the PowerShell way - Part 8: Service accounts

9. Managing Services the PowerShell way - Part 9: Eventing

10. Managing Services the PowerShell way - Part 10: Event queries with CIM

5 CO MMENTS

Matt
7 years ago

I created a very low-tech script that I've found quite useful to show just services which aren't 'default'
within our company

function show-nonstandardservices {
[CmdletBinding()]
Param ($P_SERVER = ".")
$ARR_USUAL_SERVICES = "x", "x"
$ARR_USUAL_SERVICES += "AeLookupSvc" # Application Experience
$ARR_USUAL_SERVICES += "Alerter" # Alerter
$ARR_USUAL_SERVICES += "ALG" # Application Layer Gateway Service

get-wmiobject win32_service -computername $P_SERVER |


where { $ARR_USUAL_SERVICES -notcontains $_.name } |
select name, DisplayName |
sort -uniq name
}
set-alias sserv show-nonstandardservices

This gives me a really quick way of finding out (or reminding myself) what a server does.

1+

REPLY

Jeffery Hicks (@JeffHicks)


7 years ago

Nice. I hope you don't mind but let me steer you in the right direction to make this a little better, yet
still retain your quick and dirty approach. Here's my tweak:

function show-nonstandardservices {
[CmdletBinding()]
Param (
[string]$Computername = $env:computername,
[string[]]$UsualServices=@("AeLookupSvc","Alerter","ALG","BITS","Spooler",
"LanManServer","LanManWorkstation","Wuauserv")
)

get-wmiobject win32_service -computername $computername |


where { $UsualServices -notcontains $_.name }

}
First, use standard parameter names like Computername. I would also make this a bit more flexible.
It looks like you are defining all of your accepted services in the function. So why not make it a
parameter with a default setting of array names. This way you can specify a different list for a
different server.

PS C:\> show-nonstandardservices -computername SERVER01 -UsualServices (get-content


c:\work\SRV1-Allowed.txt) | Select Name,Displayname,State

I also suggest taking out the Select and sort from the function. What if you want to see what services
are non-standard but also
their state? Or save all the information to a CSV file? Don't script yourself into a corner. Even for "low
tech", try to maintain some flexibility.

1+

REPLY

Matt
7 years ago

>> I hope you don’t mind but let me steer you in the right direction

No, I don't mind at all - I'm really grateful for the suggestions! I like the idea of having a
parameterized 'usual' list. The $P_SERVER is, I'm afraid, a hangover from some other programming
languages convention. Old dogs can learn new tricks....but sometimes it takes a while!

Thanks again, Matt

REPLY

AG
5 years ago

Hello,

These postings are really helping me learn and reduce some of my manual work. I am hoping you
might be able to assist me with the below script. What I am trying to do below is to go through each
service in an array and check the status and if the status is not stopped, I want to terminate the
process. I am not able to capture the status message. Can you advise what I am doing wrong or
steer me in the right direction

$Services = Get-Content C:\Script\Services_UAT.txt


$Logfile = "C:\Script\Log\Status_ $(Get-Date -f yyyy-MM-dd).log"

Function LogWrite
{
Param ([string]$logstring)

Add-content $Logfile -value $logstring


}

Write-Host -foregroundcolor cyan " Check UAT Services Status on Servers ..."
LogWrite -foregroundcolor cyan " Check UAT Services Status on Servers ..."

foreach ($strService in $Services)


{
IF ($strService -match "Prod_APP1_")
{
$strComputer = "APP1"
}

IF ($strService -match "Prod_APP2_")


{
$strComputer = "APP2"
}

IF ($strService -match "UAT_APP2_C")


{
$strComputer = "APP2"
}

IF ($strService -match "UAT_APP1_")


{
$strComputer = "APPUAT1"
}

$strClass = "win32_service"
$objWmiService = Get-Wmiobject -Class $strClass -computer $strComputer -filter "name =
'$strService'"

Write-Host " Checking the $strService service status on $strComputer now ..."
LogWrite " Checking the $strService service status on $strComputer now ..."
$rtn = get-service -computer $strComputer -name "$strService" | select Status

if($rtn -ne "@{Status=Stopped}")


{
Write-Host -foregroundcolor red " $strService service on $strComputer reports service Status as
$rtn. Terminating Service now..."
LogWrite -foregroundcolor red " $strService service on $strComputer reports service Status as $rtn.
Terminating Service now..."

Clear-Host
Stop-Process -name $strService -computer $strComputer

Write-Host -foregroundcolor green " $strService service on $strComputer Terminated..."


LogWrite -foregroundcolor green " $strService service on $strComputer Terminated..."
}
else
{
Write-Host -foregroundcolor green " $strService service on $strComputer reports service Status as
$rtn"
LogWrite -foregroundcolor green " $strService service on $strComputer reports service Status as
$rtn"
}
}

Thanks for all your help in advance.

With Regards,

1+

REPLY
Jeffery Hicks (@JeffHicks)
5 years ago

The function you wrote, LogWrite has a single parameter, -LogString, yet you are calling it with a -
foregroundcolor parameter which doesn't exist. Get rid of it.

LogWrite -foregroundcolor green " $strService service on $strComputer reports service Status as
$rtn"

1+

REPLY

Leave a reply

Your email address will not be published. Required fields are marked *

Comment

Source

Notify me of followup comments via e-mail

Name *

Email *

Website

POST COMMENT

Receive new post notifications


Follow 4sysops

Subscribe to post not cations


Name

Email Address

email@domain.com

Subscribe

Reviews
SmartDeploy: Easy software and OS deployment
Tue, Oct 1 2019

Specops Password Auditor v7.2: New features


Thu, Sep 12 2019

EMCO Ping Monitor Enterprise v7 new features


Tue, Sep 10 2019

Complete network visibility with SolarWinds Log and Network Performance Pack
Wed, Sep 4 2019

Specops password policy v7.2: New features


Mon, Sep 2 2019

Nakivo Backup & Replication 9.0 for Windows Server 2019


Wed, Aug 28 2019

CloudShow – Hosted digital signage for just about any device


Tue, Aug 27 2019

PA Server Monitor for Windows and Linux


Wed, Aug 21 2019

SolarWinds Security Event Manager: Threat detection and remediation


Thu, Aug 8 2019

NetCrunch 10.6 – Fast and easy-to-use network monitoring


Tue, Jul 23 2019

Azure and web automation with VisualCron


Wed, Jul 17 2019

Review: Veeam Backup & Replication Community Edition


Thu, May 30 2019
Power Admin File Sight: Protect and audit file servers
Thu, May 2 2019

3CX VoIP phone system v16: New features and improvements


Wed, Apr 24 2019

EventSentry 4.0: SIEM with Active Directory monitoring


Tue, Apr 23 2019

Site Wide Activities [RSS]

Viewing 1 - 10 of 10 items

Search

Twitter  Facebook LinkedIn  RSS


Subscribe to post noti cations
Name

Email Address

email@domain.com

Subscribe

Follow 4sysops

© 4sysops 2006 - 2019


Windows Server 2012 Server Core - Part 2: Fire and forget   Upgrading your vCenter Environment to vSphere 5.1

You might also like