Last Update: Sep 04, 2024 | Published: Apr 20, 2016
In this article, I’ll show you how to identify services that have IIS installed. I’m using IIS for the sake of my demonstrations, but you could apply this article to any product or service. One of the first questions to ask is what is an authoritative indicator? There could be more than one, but once you know what to look for, then it’s a simple matter of finding the corresponding PowerShell commands to retrieve that information.
In the case of IIS, the first thing I would check is if the Web-Server feature is installed using Get-WindowsFeature.
Get-WindowsFeature -Name Web* -ComputerName chi-web02
I picked a server that I already knew had this feature installed.
You can simplify this type of query by only getting features that are installed. Remember, this looks like fancy text, but there are objects backing it and one of the properties is Installed, which has a Boolean, or True/False value.
Get-WindowsFeature -Name Web* -ComputerName chi-web02 | where installed
So let’s take this idea and scale it out to filter a text list of computers. The only computer names I want to see at the end are those that have the Web-Server feature installed.
get-content c:workservers.txt | where { Get-WindowsFeature -Name Web-Server -ComputerName $_ | Where Installed}
This gets a little tricky because I have a nested Where-Object statement. If the computer does not have the Web-Server feature installed, then there will be nothing in the pipeline. The only names that come through will be those that have the feature installed, which in my list is three servers.
If you can use a Windows feature to identify what is installed, then I think that is the smart way to go.
But let’s say this approach won’t work for what you need to test, or in keeping with my IIS example, it won’t work on all platforms such as client machines. Then I’d ask if there is a particular service you can check? In my current example, of course there is.
You could try a command like this:
get-content C:workservers.txt | where {Get-Service w3svc -ComputerName $_}
By using this command, you’ll also get a lot of errors because Get-Service throws an exception if it can’t find the service. The easy solution is to temporarily turn errors off because we really don’t care about those computers.
get-content C:workservers.txt | where {Get-Service w3svc -ComputerName $_ -ErrorAction SilentlyContinue}
Or perhaps you want to include the service status:
get-content C:workservers.txt | foreach {Get-Service w3svc -ComputerName $_ -ErrorAction SilentlyContinue} | Select Machinename,Name,Status
In this case, I want to get the actual service.
Using Get-Service requires a legacy connection to the server. You could achieve similar results with WMI using Get-WmiObject or Get-CimInstance.
get-ciminstance -class Win32_service -filter "name='w3svc'" -computername (get-content c:workservers.txt)
In this example, I’m processing all the computer names at once with a nested pipeline.
The last way to check might be looking for a particular process. If I were searching for DNS, I could use either of these approaches:
get-content c:workservers.txt | where { get-process DNS -ComputerName $_ -ErrorAction SilentlyContinue} get-ciminstance -ClassName win32_process -filter "name='dns.exe'" -ComputerName (get-content c:workservers.txt)
Unfortunately, IIS doesn’t work that way. I know from looking at the web server that the IIS process has a start command like this:
It will take a little work, but I should still be able to filter processes on multiple computers looking for a similar line.
Get-CimInstance -ClassName win32_process -filter "Commandline like '%iissvcs'" -ComputerName (get-content c:workservers.txt) | select ProcessID,Name,Commandline,PSComputername
And sure enough I get the same servers:
Need to identify what is running where? With a little research and planning it shouldn’t be that difficult with PowerShell. Hopefully at least one of these techniques will work for you. If not, please let me know in the article comments below.