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.
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/
I know you're asking for VB solutions, I don't really know VB, I'm more of a C# person. Anyway, here is a little bit of C#.NET code taken from an app I wrote some time ago which lists the IIS virtual directories...
using System.DirectoryServices;
private DirectoryEntry _iisServer = null;
private DirectoryEntry iisServer
{
get
{
if (_iisServer == null)
{
string path = string.Format("IIS://{0}/W3SVC/1", serverName);
_iisServer = new DirectoryEntry(path);
}
return _iisServer;
}
}
private IDictionary<string, DirectoryEntry> _virtualDirectories = null;
private IDictionary<string, DirectoryEntry> virtualDirectories
{
get
{
if (_virtualDirectories == null)
{
_virtualDirectories = new Dictionary<string, DirectoryEntry>();
DirectoryEntry folderRoot = iisServer.Children.Find("Root", VirDirSchemaName);
foreach (DirectoryEntry virtualDirectory in folderRoot.Children)
{
_virtualDirectories.Add(virtualDirectory.Name, virtualDirectory);
}
}
return _virtualDirectories;
}
}
Hopefully you will be able to get the general idea from that.
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;
}
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);
}
}