
close
close
Upcoming FREE Conference on Identity Management and Privileged Access Management
Regular readers of my articles know that I am a big proponent of managing at scale. Instead of taking the approach to execute tasks individually, management at scale means that we’re looking for a way to execute multiple tasks with a single command. Fortunately, PowerShell makes this an easy proposition, once you get your head around the concept.
In this article, I want to demonstrate this concept by checking the status of critical services on my domain controllers. This is a task that you most likely perform already. Instead of navigating through cumbersome GUI-based tools or remote desktop sessions, you can use PowerShell to easily manage the task at scale.
Let’s start with a variable of domain controller names.
$dcs = "chi-dc01","chi-dc02","chi-dc04"
I’m manually entering the names, but you could just as easily read in the contents of a text file, import a CSV, or even query Active Directory if you have the AD module installed.
$dcs = (Get-ADDomain).ReplicaDirectoryServers
In my domain, all the domain controllers are also DNS servers. Because I plan on using Get-Service, and the cmdlet allows me to query for multiple services, I’ll create a variable with the service names I want to check.
$svcs = "adws","dns","kdc","netlogon"
At this point, I can let PowerShell do its thing and look at all of these services on the collection of servers.
Get-Service -name $svcs -ComputerName $dcs
Getting status of multiple services from multiple computers (Image Credit: Jeff Hicks)
Getting service properties with Get-Member (Image Credit: Jeff Hicks)
Get-Service -name $svcs -ComputerName $dcs | Select Machinename,Name,Status
Service statuses (Image Credit: Jeff Hicks)
Get-Service -name $svcs -ComputerName $dcs | Select @{Name="Computername";Expression={$_.Machinename}}, DisplayName,Status | Format-Table -AutoSize
I’m using a custom hashtable with Select-Object to define a new property called Computername, which will have a value of the MachineName property for each object.
Formatted service status results (Image Credit: Jeff Hicks)
Get-Service -name $svcs -ComputerName $dcs | Sort Machinename | Format-Table -group @{Name="Computername";Expression={$_.Machinename.toUpper()}} -Property Name,Displayname,Status
Results organized by domain controller (Image Credit: Jeff Hicks)
Get-Service -name $svcs -ComputerName $dcs | Sort Displayname | Format-Table -group @{Name="Service";Expression={"$($_.Displayname) [$($_.name)]"}} -Property @{Name="Computername";Expression={$_.Machinename.toUpper()}},Status -AutoSize
Formatted results by service (Image Credit: Jeff Hicks)
The tricky part of WMI is building a filter that only returns the services we’re interested in. The WMI filter uses the legacy operators, not PowerShell operators. In my example, I need to construct a WMI filter like this.
$filter = "Name = 'ADS' OR Name = 'DNS' OR Name = 'KDC' OR Name = 'NetLogon'"
Nothing is case sensitive, but you do need to quote the service names. I can use the filter like this:
Get-WmiObject -Class Win32_service -filter $filter -ComputerName $dcs | Select PSComputername,Name,Displayname,State,StartMode | format-table -autosize
I’ve already done the step of running a similar WMI command through Get-Member to discover the property names. WMI even offers some additional information that I can’t get with Get-Service.
Service status via WMI (Image Credit: Jeff Hicks)
Now, perhaps what you are really interested in are services that aren’t running. With WMI, this is pretty easy to do. Here’s a revised filter.
$filter = "(Name = 'ADS' OR Name = 'DNS' OR Name = 'KDC' OR Name = 'NetLogon') AND State<>'Running'"
Notice the use of parentheses because I want services with any of those names AND the state not equal to running. All I have to do is re-run the Get-WmiObject command.
Filtered WMI results (Image Credit: Jeff Hicks)
Get-Service -name $svcs -ComputerName $dcs | where {$_.Status -ne "running"} | Select Machinename,Name,Displayname,Status | format-table -AutoSize
Filtered results with Where-Object (Image Credit: Jeff Hicks)
More in PowerShell
Most popular on petri