How To: Use Microsoft.Web.Administration from Powershell

Powershell has become a defacto scripting environment for a lot of  companies and rightly so considering its capabilities.
However, not every place do we find all modules loaded into powershell as one would like for the ease of scripting. I faced a similiar situation wherein I wanted to perform few admin tasks on an IIS box and din't have the IIS powershell snap-in installed. Wish the server was Windows Server 2008 R2 (IIS module is out-of-the-box loaded). There are more than a couple ways which could handle the script I was aiming for. Nevertheless, I thought it was a great opportunity to check out this functionality.

Essentially, I had to do the following:
1. Get a particular website status. Lets say "MyWebSite" in this case.
2. Start the website if it's in a stopped state.
2. Next, go through all the application pools associated to the website.
2. Check their status.
3. Start the AppPools if stopped.
4. Get all the information into a log file.
We were going to run this script from a central repository, which, would execute the script locally on a pre-defined set of servers. However, this script can be easily modified to run using Powershell V2 remoting capabilities.

Note: If you are not interested in the detailed working of the script just scroll down to get the complete script.

To start with we need to load the assembly itself. This is how it's done:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")

Next is to create an instance of ServerManager class using which we can access the entire configuration. Developers would be familiar with the ServerManager class. Anyhow, more information is available here. Creating an instance is actually very as simple.

$iis = New-Object Microsoft.Web.Administration.ServerManager

That's it. Now, using this we can access information on IIS Sites, Applications, Worker Processes and much more. A simple example of a script would be to check the "MyWebSite" status and then act accordingly.

Here's how you can get that:

            [string] $host2 = hostname
            Write-Host "Server name: $host2"


             $site_name = $iis.sites["MyWebSite"]


           Write-Host "$site_name"


            $site_state = $iis.sites["MyWebSite"].state


            Write-Host "$site_state"

Once we get the state of "MyWebSite", we can start the website if it is stopped.
       if ($iis.sites["MyWebSite"].state -eq "Stopped")
           {
                 $iis.sites["MyWebSite"].start()
                 Write-Host "WebSite Started"
            }

Next, I wanted to do the same for all the Application Pools associated with "MyWebSite".

    foreach ($apppool in $site.applications)
        {
                $appPoolName = $apppool.applicationpoolname
                $apppoolobject = $iis.ApplicationPools[$appPoolName]
                      if ($apppoolobject.state -eq "Stopped")
                            {
                                  Write-Output $appPoolName $("is in stopped state... Attempting to Re-Start `n")
                                   [void]$apppoolobject.start()
                                       If ($apppoolobject.start() -eq "1")
                                               {
                                                       # Write into log File
                                                }
                                        Else
                                               {
                                                    # Write into log file
                                                }


                             }
                       else
                            {
                                  Write-Output $("$appPoolName is already started `n `n")
                            }
         }
 
In the above code once we get the application pool name all we do it try to start the AppPool. I have seen that sometimes even after we do a apppool.start() the application pool doesnt start properly, there we have an additional IfElse to check the app pool condition post-start.
 
To run this script and collect the output into a log file, you would need to execute it in the following manner.
 
.\IISStatus.ps1 Out-File IISStatus.log -append
 
The output from your server will now be saved in IISStatus.log. I am using -append as we were collecting information from more than 100 servers. Also, if you are running this script for multiple server from a share location (My Case) i recommend giving a shared location for IISStatus.log as well. But make sure that the shared location is accessible over the network before you execute the script.
 
Here's the whole script (IISStatus.ps1) and how the log file (IISStatus.log) looks like:
 
$iis = New-Object Microsoft.Web.Administration.ServerManager
[string] $host2 = hostname


Write-Host "Server name: $host2"
$site_name = $iis.sites["MyWebSite"]
Write-Host "$site_name"
$site_state = $iis.sites["MyWebSite"].state
Write-Host "$site_state
if ($site_state -eq "Stopped")
 {
    Write-Output $("WebSite is currently stopped... `n")
    Write-Output $("Starting the website ($site) `n")
     $iis.sites["MyWebSite"].start()
     Write-Output $("WebSite Started ($site) `n")
 }
else
 {
     Write-Output $("Website ($site) is already started... Checking the Application Pools Now `n"
}
if($site.name -eq "MyWebSite" )
{
    foreach ($apppool in $site.applications)
         {
               $appPoolName = $apppool.applicationpoolname
               $apppoolobject = $iis.ApplicationPools[$appPoolName]
                  if ($apppoolobject.state -eq "Stopped")
                      {
                           Write-Output $appPoolName $("is in stopped state... Attempting to Re-Start `n")
                            [void]$apppoolobject.start()
                              If ($apppoolobject.start() -eq "1")
                                     {
                                          Write-Output $("$appPoolName has been re-started `n`n")
                                          Write-Output $("--------------------------------------------")
                                          Write-Output $("--------------------------------------------")
                                      }
                               Else
                                     {
                                          Write-Output $("$appPoolName could not be re-started `n`n")
                                          Write-Output $("--------------------------------------------")
                                          Write-Output $("--------------------------------------------")
                                     }
                       }
                else
                      {
                          Write-Output $("$appPoolName is already started `n `n")
                      }
       }
}
Write-Output $("--------------------------------------------")
Write-Output $("--------------------------------------------")

IISStatus.log:

Server Name: Servername
Site Name: MyWebSite
Current Website Status: Started
Website (MyWebSite) is already started... Checking the Application Pools Now
AppPool1 is already started
AppPool2 is already started
--------------------------------------------
--------------------------------------------


Server Name: Servername
Site Name: MyWebSite
Current Website Status: Stopped
WebSite is currently stopped...
Starting the website (MyWebSite)
Unknown
WebSite Started (MyWebSite)
AppPool1 is in stopped state... Attempting to Re-Start
AppPool1 has been re-started
--------------------------------------------
--------------------------------------------
AppPool2 is in stopped state... Attempting to Re-Start
AppPool2 has been re-started
--------------------------------------------
--------------------------------------------
--------------------------------------------
--------------------------------------------

No Comments