HOWTO: Enumerate IIS website configuration (VBScript using ADSI)

A powerful but often under-utilized and misunderstood feature of IIS is its programmatic configuration APIs. On the one hand, all IIS administrative APIs allow programmatic, automated, and unattend configuration of IIS. On the other hand, it can be hard to choose which administration model (and resulting API) to use, and sample code to get started on the interfaces are hard to come by, as the following question illustrates...

Question:

Hi, all.

My ultimate goal is to script out a solution which you would get if you opened up IISAdmin and exported the website list to a file. If someone knows of where something like that can be found, please let me in on it.

I've manage to cobble the below together after several hours of rooting through Google and the MSDN pages...

Set IISOBJ = getObject("IIS://LocalHost/W3SVC")
For each Object in IISOBJ
if (Object.Class = "IIsWebServer") then
WScript.Echo "server name? " & " Description " &
Object.ServerComment & " Identifier " & Object.Name & " State, up or
down? " & Object.ServerState & " Headers? " & " IP address? " & " port?
" & " SSL Port? "
end if
next

I think I'm spinning my wheels at this point, there's a number of items I'm still missing, like getting a website state, headers, site IP address and port information. Any thoughts or good pointers on how to get it?

I've got a decade more unix scripting knowledge under my belt, but it's pretty useless to me in this instance.

Thanks for your time.

Answer:

Well, hopefully, you do not need to look further than here. :-)

Based on your example code, it appears that you are looking for a VBScript based script using the IIS ADSI API. I whipped together a fairly detailed starter sample at the end of this entry to do what you are asking for, including:

  • Enumerate all websites on a given server or a remote server (assumes running user has necessary credentials on remote server).
  • Display all HTTP/HTTPS bindings of each website (IP, Port, Host Header)
  • Runtime state (such as whether the website is started, stopped, paused, etc)
  • Some other properties, like Log file directory and friendly website description

This sample should have enough details to get you started. Use <EnumWebSites.vbs> [RemoteServerName] to enumerate websites on a remote server.

Example output:

 Enumerating websites on localhost

Site ID = 1
Comment = "Default WebSite"
State   = Started (MD_SERVER_STATE_STARTED)
LogDir  = %WinDir%\System32\LogFiles
IP Address      Port    Host
All Unassigned  80      *
1.2.3.4         81      *
12.34.56.78     82      HostHeader
All Unassigned  443     *

Site ID = 2
Comment = "Administration Web Site"
State   = Started (MD_SERVER_STATE_STOPPED)
LogDir  = %WinDir%\System32\LogFiles
IP Address      Port    Host
All Unassigned  8734    *
All Unassigned  443     *

Here are some other useful links (if you want to enumerate other website properties or even other objects like Virtual Directories or Web Applications):

If you have other questions, feel free to post comments on this post or send them via the blog's "contact" link.

Enjoy.

//David

 OPTION EXPLICIT

DIM CRLF, TAB
DIM strServer
DIM objWebService

TAB  = CHR( 9 )
CRLF = CHR( 13 ) & CHR( 10 )

IF WScript.Arguments.Length = 1 THEN
    strServer = WScript.Arguments( 0 )
ELSE
    strServer = "localhost"
END IF

WScript.Echo "Enumerating websites on " & strServer & CRLF
SET objWebService = GetObject( "IIS://" & strServer & "/W3SVC" )
EnumWebsites objWebService


SUB EnumWebsites( objWebService )
    DIM objWebServer, strBindings

    FOR EACH objWebServer IN objWebService
        IF objWebserver.Class = "IIsWebServer" THEN
            WScript.Echo _
                "Site ID = " & objWebserver.Name & CRLF & _
                "Comment = """ & objWebServer.ServerComment & """ " & CRLF & _
                "State   = " & State2Desc( objWebserver.ServerState ) & CRLF & _
                "LogDir  = " & objWebServer.LogFileDirectory & _
                ""

            ' Enumerate the HTTP bindings (ServerBindings) and
            ' SSL bindings (SecureBindings)
            strBindings = EnumBindings( objWebServer.ServerBindings ) & _
                          EnumBindings( objWebServer.SecureBindings )
            IF NOT strBindings = "" THEN
                WScript.Echo "IP Address" & TAB & _
                             "Port" & TAB & _
                             "Host" & CRLF & _
                             strBindings
            END IF
        END IF
    NEXT

END SUB

FUNCTION EnumBindings( objBindingList )
    DIM i, strIP, strPort, strHost
    DIM reBinding, reMatch, reMatches
    SET reBinding = NEW RegExp
    reBinding.Pattern = "([^:]*):([^:]*):(.*)"

    FOR i = LBOUND( objBindingList ) TO UBOUND( objBindingList )
        ' objBindingList( i ) is a string looking like IP:Port:Host
        SET reMatches = reBinding.Execute( objBindingList( i ) )
        FOR EACH reMatch IN reMatches
            strIP = reMatch.SubMatches( 0 )
            strPort = reMatch.SubMatches( 1 )
            strHost = reMatch.SubMatches( 2 )

            ' Do some pretty processing
            IF strIP = "" THEN strIP = "All Unassigned"
            IF strHost = "" THEN strHost = "*"
            IF LEN( strIP ) < 8 THEN strIP = strIP & TAB

            EnumBindings = EnumBindings & _
                           strIP & TAB & _
                           strPort & TAB & _
                           strHost & TAB & _
                           ""
        NEXT

        EnumBindings = EnumBindings & CRLF
    NEXT

END FUNCTION

FUNCTION State2Desc( nState )
    SELECT CASE nState
    CASE 1
        State2Desc = "Starting (MD_SERVER_STATE_STARTING)"
    CASE 2
        State2Desc = "Started (MD_SERVER_STATE_STARTED)"
    CASE 3
        State2Desc = "Stopping (MD_SERVER_STATE_STOPPING)"
    CASE 4
        State2Desc = "Stopped (MD_SERVER_STATE_STOPPED)"
    CASE 5
        State2Desc = "Pausing (MD_SERVER_STATE_PAUSING)"
    CASE 6
        State2Desc = "Paused (MD_SERVER_STATE_PAUSED)"
    CASE 7
        State2Desc = "Continuing (MD_SERVER_STATE_CONTINUING)"
    CASE ELSE
        State2Desc = "Unknown state"
    END SELECT

END FUNCTION