How to Programmatically Modify the IIS Virtual Directory

If you have more than a dozen web servers in a cluster with identical setting, and you need to update the virtual directory, it is much more convenient to write a simple program to update it. This example shows how to do it. In this case, this snippet will change the physical path of a virtual directory.

This snippet works on IIS 6 and IIS 7. PowerShell may not be installed in Server 2003, to make this snippet more generic, this snippet is written in C#, otherwise, PowerShell script may be a better option.

 private const string MetabasePath = "IIS://Localhost/W3SVC/1/Root";

//Get the virtual directory of IIS.
private static DirectoryEntry GetVirtualDirectory(DirectoryEntry IISDirectory, string vDirName)
{
    string ClassName = IISDirectory.SchemaClassName.ToString();

    if (!((ClassName.EndsWith("Server")) || (ClassName.EndsWith("VirtualDir"))))
    {
        throw new Exception(String.Format("Virtual Directory can be updated under site or virual directory node. Metabase:{0}, SchemaClassName={1}", MetabasePath, ClassName));
    }

    //Iterate through the children, as Find() method is having an issue with IIS 6, if more than one thread is accessing IIS, an AccessViolationException is thrown.
    //The fix is applying the a hot fix https://support.microsoft.com/kb/946517. Either use Find(), or use this method below.
    //Since IIS may not have the hot fix installed, this sample iterates the children.
    foreach (DirectoryEntry VirtualDir in IISDirectory.Children)
        if (String.Compare(VirtualDir.Name, vDirName, StringComparison.OrdinalIgnoreCase) == 0)
            return VirtualDir;

    return null;
}

//Update the physical path of the site.
private static void UpdatePhysicalPath(string virtualDirectoryName, string newPath)
{
    using (DirectoryEntry Site = new DirectoryEntry(MetabasePath))
    {
        DirectoryEntry StatsNet = GetVirtualDirectory(Site, virtualDirectoryName);

        if (StatsNet == null)
            throw new Exception(String.Format("Site not found. Metabase={0}, virtualDirectory={1}", MetabasePath, virtualDirectoryName));

        StatsNet.Properties["Path"][0] = newPath;
        StatsNet.CommitChanges();
    }
}

static void Main(string[] args)
{
    UpdatePhysicalPath("MySite", @"d:\http\MyNewSite");
}

That snippet above shows how to change the path, there are a lot of properties that can be changed, at least this shows the basic idea.