Use PowerShell to Monitor IIS Websites and Application Pools

I recently received a request to write a script for monitoring IIS websites and their application pools on a specific Windows 2012 R2 server and start them if they were stopped. This is something I created fairly quickly and thought I would share.

I always try to centralize any scripts I write and have them run on a job server instead of the actual server they're querying. That way I don't have multiple versions of the same script floating around on different servers. I can easily use this same script on multiple servers by simply adding additional server names to the $Servers variable. The list of servers can be hard coded like I've done in this scenario, they could be retrieved from Active Directory, a text file, from a SQL Server database, or from almost any place you could imagine.

For some reason, the WebAdministration PowerShell module didn't seem to want to auto-load even though this particular server has Windows PowerShell version 4.0 installed. I had no problem manually importing it though.

 1$Servers = 'Server01'
 2Invoke-Command -ComputerName $Servers {
 3    Import-Module -Name WebAdministration
 4    $Websites  = Get-Website | Where-Object serverAutoStart -eq $true
 5    foreach ($Website in $Websites) {
 6        switch ($Website) {
 7            {(Get-WebAppPoolState -Name $_.applicationPool).Value -eq 'Stopped'} {Start-WebAppPool -Name $_.applicationPool}
 8            {$_.State -eq 'Stopped'} {Start-Website -Name $Website.Name}
 9        }
10    }

This script is fairly simple. It retrieves a list of websites that are set to start automatically. Originally, I had retrieved all of the websites and used an If statement inside the Switch statement to filter down to only the ones that were set to automatically start, but this is one scenario where it's more efficient and cleaner to filter when retrieving the list of websites using Where-Object. If Get-Website had a parameter for filtering on the serverAutoStart property, that would be even more efficient.

The logic is that if they're set to auto start, then they should be running. It checks to see if the application pool is started and starts it if not. Then it checks to see if the website is running and starts it if not. Like I said, simple.

I decided to use a Switch statement instead of several If statements and notice that it doesn't really matter what you put in the items for the switch statement. Regardless if they're related to the variable you're testing or not, if they evaluate to true, the code in them will run.

Set it up as a scheduled task to run at a periodic interval and you're all set. PowerShell eventing might also be another possibility instead of a scheduled task if you want the script to be a little smarter.

Depending on the version of Windows Server and/or IIS, you may have an IIS PowerShell module by a different name that contains different commands. You could also use the IIS WMI classes that exist in the MicrosoftIISv2 namespace which require the IIS 6 WMI Compatibility component to be installed.

1Install-WindowsFeature -Name Web-WMI

Using the Carbon (third party) PowerShell module is another possibility. If you happen to go this route, be sure to take a look at the methods on the Get-IisWebsite and Get-IisAppPool commands as there aren't dedicated commands to start websites or app pools, but there are methods to accomplish these actions.