IIS Web Site Port Numbers

Thanks for all the interesting comments on my previous post. I plan to talk more about the subject of code quality and pragmatism in the future.

A developer recently asked me how she could programmatically determine the port number for a particular IIS web site running on Windows Server 2003. One of the nice things about IIS 6 is that it stores the metabase as an XML document under the system directory. This provides a much simpler mechanism (in my opinion) for querying and configuring IIS compared to what was available in older versions, as long as you’re familiar with the schema. The code snippet below prints out the web sites in IIS and their respective port numbers.

 

// Get the path to the metabase document.

String^ path = Environment::GetFolderPath(Environment::SpecialFolder::System);

path = IO::Path::Combine(path,
                         "inetsrv\\metabase.xml");

// Create an XPathNavigator to search the document.

Xml::XPath::XPathDocument^ document = gcnew Xml::XPath::XPathDocument(path);
Xml::XPath::XPathNavigator^ navigator = document->CreateNavigator();
navigator->MoveToChild(Xml::XPath::XPathNodeType::Element);

// Determine the namespace for the document and associate it with a prefix
// to use in expressions.

Xml::XmlNamespaceManager^ resolver = gcnew Xml::XmlNamespaceManager(document->NameTable);
String^ defaultNamespace = navigator->LookupNamespace(String::Empty);

resolver->AddNamespace("iis",
                       defaultNamespace);

// Iterate over all IIsWebServer elements with a ServerBindings attribute.

Xml::XPath::XPathNodeIterator^ iter = navigator->Select("//iis:IIsWebServer[@ServerBindings]",
                                                        resolver);

// The regular expression allows us to easily extract the port number from
// the ip:port:host tuple.

Text::RegularExpressions::Regex^ port = gcnew Text::RegularExpressions::Regex("^[^:]*:(\\d+):[^:]*$");

while (iter->MoveNext())
{
    Xml::XPath::XPathNavigator^ node = iter->Current;

    // Only print the server details if the expression matches a port number.

    Text::RegularExpressions::Match^ match = port->Match(node->GetAttribute("ServerBindings",
                                                                            String::Empty));

    if (match->Success)
    {
        Console::Write("Description: ");

        Console::WriteLine(node->GetAttribute("ServerComment",
                                              String::Empty));

        Console::Write("Location: ");

        Console::WriteLine(node->GetAttribute("Location",
                                              String::Empty));

        Console::Write("Port: ");
        Console::WriteLine(match->Groups[1]->Value);
        Console::WriteLine();
    }
}

Here is the output I get on one of my servers:

 

Description: Default Web Site
Location: /LM/W3SVC/1
Port: 80

Description: Microsoft SharePoint Administration
Location: /LM/W3SVC/2
Port: 3062

Description: Virtual Server
Location: /LM/W3SVC/3
Port: 1024


© 2004 Kenny Kerr

 

No Comments