Using LINQ with Microsoft.Web.Administration

With the upcoming release of .NET 3.5 and LINQ I thought it would be interesting to show some of the cool things you can do with IIS 7 and LINQ. Everything that I will do can be done with C# 2.0 code but it would take me several lines of code to write them but thanks to LINQ you can do them in about a line or two.

Let's start with a very basic example that does not use LINQ but just M.W.A (Microsoft.Web.Administration) and then start adding interesting things to it.

The following code just iterates the sites in IIS and displays their name.

using System;
using System.Linq;
using Microsoft.Web.Administration;
class Program {
    static void Main(string[] args) {
        using (ServerManager serverManager = new ServerManager()) {

            var sites = serverManager.Sites;
            foreach (Site site in sites) {
                Console.WriteLine(site.Name);
            }
        }
    }
}

Now, let's say I wanted to have them sorted by their name. This is where LINQ starts being useful

    using (ServerManager serverManager = new ServerManager()) {

        var sites = (from site in serverManager.Sites
            orderby site.Name
            select site);

        foreach (Site site in sites) {
            Console.WriteLine(site.Name);
        }
    }

Say you want to start all the sites that are stopped:

    using (ServerManager serverManager = new ServerManager()) {

        var sites = (from site in serverManager.Sites
            where site.State == ObjectState.Stopped
            orderby site.Name
            select site);

        foreach (Site site in sites) {
            site.Start();
        }
    }

OK, now let's imagine I want to find all the applications that are configured to run in the Default ApplicationPool and move them to run in my NewAppPool. This would take me a lot more lines of code but now I can just do:

    using (ServerManager serverManager = new ServerManager()) {

        var apps = (from site in serverManager.Sites
            from app in site.Applications
            where app.ApplicationPoolName.Equals("DefaultAppPool", StringComparison.OrdinalIgnoreCase)
            select app);

        foreach (Application app in apps) {
            app.ApplicationPoolName = "NewAppPool";
        }

        serverManager.CommitChanges();
    }

Now let's say I want to find the top 20 distinct URL's of all the requests running in all my worker processes that has taken more than 1 second.

    using (ServerManager serverManager = new ServerManager()) {

        var requests = (
            from wp in serverManager.WorkerProcesses
            from request in wp.GetRequests(1000)
            orderby request.TimeElapsed descending
            select request).Distinct().Take(20);

        foreach (Request request in requests) {
            Console.WriteLine(request.Url);
    }
}

OK, finally let's say I want to display a table of all the applications running under DefaultAppPool and display if Anonymous authentication is enabled or not. (Now this one is almost on the edge of "you should do it differently, but it is Ok if you are only reading a single value from the section):

    using (ServerManager serverManager = new ServerManager()) {

        var items = from site in serverManager.Sites
            from app in site.Applications
            where app.ApplicationPoolName.Equals("DefaultAppPool", StringComparison.OrdinalIgnoreCase)
            orderby site.Name, app.Path
            select new {
                Site = site,
                Application = app,
                AnoymousEnabled = ((bool)app.GetWebConfiguration().GetSection("system.webServer/security/authentication/anonymousAuthentication")["enabled"])
            };

        foreach (var item in items) {
            Console.WriteLine("Site:{0,-18} App:{1, -10} Anonymous Enabled:{2}",
                item.Site.Name, item.Application.Path, item.AnoymousEnabled);
        }
    }

As you can see LINQ is an incredibly useful feature in C# 3.0 and in conjunction with Microsoft.Web.Administration allows you to do incredibly complex operations in IIS with just few lines of code.