There are a lot of ways to do things, especially in scripting. For instance, when you search for a service that doesn’t exist, Get-Service produces a exception:
PS C:\Windows\System32\WindowsPowerShell\v1.0> Get-Service -Name ServiceDoesntExist
Get-Service : Cannot find any service with service name 'ServiceDoesntExist'.
At line:1 char:1
+ Get-Service -Name ServiceDoesntExist
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (ServiceDoesntExist:String) [Get-Service], ServiceCommandException
+ FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand
In order to trap an exception, you would do something like this:
try {
Get-Service -Name WSearch, IISAdmin -ErrorAction Stop
}
catch {
$_.Exception.Message
}
This would give you the error message that was displayed, which you could parse to get the name of the service and create a custom message.
Cannot find any service with service name 'IISAdmin'.
The pro to this is that you are only searching for certain services, but the parsing can be a pain. As you are a beginner, take a look at this approach:
$ComputerName = "Computer1", "Computer2"
foreach ($computer in $ComputerName) {
#Array of services to check
$servicesToCheck = "WSearch", "IISAdmin"
#Get all services on the computer
$services = Get-Service -ComputerName $computer | Select Name, Status
#Below we are selecting individual objects, so we want to return the results
#to a variable with all of the results
$results = foreach ($service in $servicesToCheck) {
#Query all services to get the service status
$checkService = $services | Where{ $_.Name -eq $service }
#if the computer is not null
if ($checkService) {
#Select creates a PSObject, so this should be choice 1 when creating objects
#The last property is a calculated property, since Get-Service does not contain PSComputerName, we
#create a custom property. An expression is code, so you can even call other commands like
#Get-ADComputer -ComputerName $computer | Select -ExpandProperty Description
#to put the computer's AD description here
$checkService | Select Name, Status, @{Name="ComputerName";Expression={$computer}}
}
else {
#Since the checkservice is null because the service doesn't exist, you need to generate a custom
#object. You can do the below, use [pscustomobject] or Add-Member. You've used the Add-Member, I
#think you'll see how much cleaner and easier to read the other methods are for create objects
$props = @{ComputerName=$computer;
Name=$service;
Status="Not Installed"}
New-Object -TypeName PSObject -Property $props
}
}
}
$results
This can easily converted into a function, but it’s important to understand the logic and methods used. The con of this approach is that we are getting all of the services and then searching against those results, but most systems will have a couple hundred services and there shouldn’t be a huge performance loss unless you are running this against thousands of servers. You’ll see references to filter as far left as you can, which means you want to only return what you want in the initial query. Now, let’s look at this method using WMI:
Get-WMIObject -ComputerName "Computer1", "Computer2" -Class Win32_Service -Filter "Name='ZeroConfigService' or Name='IISAdmin'" | Select PSComputerName, Name, State
WMI will only return the service if it’s installed, we are only getting the services we want (Not all services and then trying to see the service exists) and Select is creating the PSObject with all of the information you need. As I said, multiple ways to do things, but hopefully you will understand some of the logic and ways to get service information.