List all virtual directories in IIS 5,6 and 7

12,257

Solution 1

have you tried using GetObject("IIS://ServerName/W3SVC")

You do it in VBS like this

'Get the IIS Server Object
Set oW3SVC = GetObject("IIS://ServerName/W3SVC/1/ROOT")

For Each oVirtualDirectory In oW3SVC

    Set oFile = CreateObject("Scripting.FileSystemObject")
    Set oTextFile = oFile.OpenTextFile("C:\Results.txt", 8, True)

    oTextFile.WriteLine(oVirtualDirectory.class + " -" + oVirtualDirectory.Name)
    oTextFile.Close

Next
Set oTextFile = Nothing
Set oFile = Nothing

Wscript.Echo "Done"

I have an article about it here -> http://anyrest.wordpress.com/2010/02/10/how-to-list-all-websites-in-iis/

Solution 2

Here are two examples that should work across IIS 5, 6 and 7 (with IIS 6 WMI compatibility installed). I successfully tested both with IIS 5 and 7.

VBScript version

Function ListVirtualDirectories(serverName, siteId) 
    Dim webSite 
    Dim webDirectory

    On Error Resume Next 

    Set webSite = GetObject( "IIS://" & serverName & "/W3SVC/" & siteId & "/ROOT" ) 
    If ( Err <> 0 ) Then 
        Err = 0 
        Exit Function 
    Else 
        For Each webDirectory in webSite
            If webDirectory.Class = "IIsWebVirtualDir" Then 
                WScript.Echo "Found virtual directory " & webDirectory.Name
            End If 
        Next
    End If   
End Function

C# version

void ListVirtualDirectories(string serverName, int siteId)
{            
       DirectoryEntry webService = new DirectoryEntry("IIS://" + serverName + "/W3SVC/" + siteId + "/ROOT");

       foreach (DirectoryEntry webDir in webService.Children)
       {
           if (webDir.SchemaClassName.Equals("IIsWebVirtualDir"))
               Console.WriteLine("Found virtual directory {0}", webDir.Name);
       }
}

Solution 3

Here are two helper functions to add onto Garetts answer. With these, you can loop through each domain and get all its virtual directories, including ones that are not in the domains root folder.

Get Site ID from domain name:

    string GetSiteID(string domain)
    {
        string siteId = string.Empty;

        DirectoryEntry iis = new DirectoryEntry("IIS://localhost/W3SVC");
        foreach (DirectoryEntry entry in iis.Children)
            if (entry.SchemaClassName.ToLower() == "iiswebserver")
                if (entry.Properties["ServerComment"].Value.ToString().ToLower() == domain.ToLower())
                    siteId = entry.Name;

        if (string.IsNullOrEmpty(siteId))
            throw new Exception("Could not find site '" + domain + "'");

        return siteId;
    }

Get all descendant entries (recursively) for site entry

    static DirectoryEntry[] GetAllChildren(DirectoryEntry entry)
    {
        List<DirectoryEntry> children = new List<DirectoryEntry>();
        foreach (DirectoryEntry child in entry.Children)
        {
            children.Add(child);
            children.AddRange(GetAllChildren(child));
        }

        return children.ToArray();
    }

Mapping Site ID's for large number of sites

Edit: After testing this with a server containing several hundred domains, GetSiteID() performs very slow because it is enumerating all the sites again and again to get the id. The below function enumerates the sites only a single time and maps each one to its id and stores it in a dictionary. Then when you need the site id you pull it from the dictionary instead, Sites["domain"]. If you are looking up virtual directories for all sites on a server, or a large amount, the below will be much faster than GetSiteID() above.

    public static Dictionary<string, string> MapSiteIDs()
    {  
        DirectoryEntry IIS = new DirectoryEntry("IIS://localhost/W3SVC");
        Dictionary<string, string> dictionary = new Dictionary<string, string>(); // key=domain, value=siteId
        foreach (DirectoryEntry entry in IIS.Children)
        {
            if (entry.SchemaClassName.ToLower() == "iiswebserver")
            {
                string domainName = entry.Properties["ServerComment"].Value.ToString().ToLower();
                string siteID = entry.Name;
                dictionary.Add(domainName, siteID);
            }
        }

        return dictionary;
    }
Share:
12,257
Avitus
Author by

Avitus

Real Programmers don't comment their code. If it was hard to write, it should be hard to understand and even harder to modify.

Updated on June 04, 2022

Comments

  • Avitus
    Avitus about 2 years

    I am trying to create a list of all virtual directories within an IIS site. However, I have found that trying to do this varies dramatically in the older versions of IIS. In IIS 7 this is a relatively easy task via C# but I can't seem to find a good method for doing this in IIS 6 and 5.

    I have tried using the System.DirectoryServices.DirectoryEntry but that doesn't seem to give me the desired output.

    I am the server administrator so I'm open to using other things such as .vbs files that are built into IIS as well as writing my own code.