Sunday, February 15, 2009

Setup your IIS programmatically

When I was setting http handlers for a particular folder in IIS 5 and 6 one of the requirements was to do it programmatically. Using System.DirectoryServices.DirectoryEntry seems to be the easiest way to do it.
Getting access to your IIS configuration is simple:

new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC")

That's it. This will give you access to the sites folder or your IIS. You would need to go through children nodes and find your site, and then through its children all they way down to the virtual folder you want to setup. Now if you know exactly which site you want to setup you could access it by simply using full path, like this:

new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC/1/ROOT/MyTestSite")

If you have more then one web site and more then one virtual folder to deal with things are not that simple anymore. But it's not too complex either. IIS 6.0 Resource Toolkit is your friend here. Whatever you see in Metabase explorer you can find/change programmatically. For example to get the list of all web sites on your local IIS you could do the following:

var iis = new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC");
var sites = (from DirectoryEntry entry in iis.Children
where entry.SchemaClassName == "IIsWebServer"
select entry).ToList();

This will list you all web sites you have on your IIS. The root folder is normally imediatelly beneath website, you can get it like this (in this example from the first web site):

var root = (from DirectoryEntry entry in sites[0].Children
where entry.Name == "ROOT"
select entry).FirstOrDefault();

And now find a virtual folder you are looking for:

var virtualFolder
= (from DirectoryEntry entry in root.Children
where entry.Name == "MyTestSite"
select entry).FirstOrDefault();

So the pattern is clear, we go through children and we are finding what we want. Editing settings is pretty easy, if you want to create a virtual folder all you need to do is add a child to the root folder, or some other virtual folder:

root.Children.Add("AnotherVirtualFolder", "IIsWebVirtualDir");

You need to call CommitChanges method to, errr ..., commit changes you've just made, otherwise they won't be applied. Or you can add custom web folder:

var myTargetFolder = virtualFolder.Children.Add("Scripts", "IIsWebDirectory");

And now you can change properties on your folder, or on anything else really:


Again take a peek in your metabase explorer to see what you can change. In this case ScriptMaps is an array so if we want to handle only *.js files in our folder we clear all entries and then add just the one we are interested in.

Well it's pretty simple, now you can do whatever you want with your IIS. Interestingly, if you want to manipulate the Metabase during installation things might be even simpler, however there are couple of cavets along the way. More on that soon.