HOWTO: Enumerate IIS website and ftpsite configuration (VBScript using ADSI)

I recently got a request to make a script to illustrate how to enumerate useful values from both Web and FTP sites serviced by IIS, so I decided to make some additions to the original script tool located here to allow it to easily enumerate both Web and FTP sites.

The modifications basically illustrate how both the Web and FTP services have consistent programming models and mechanisms to read/change configuration values. I basically only abstracted:

  • Metabase configuration node from /W3SVC (Web) to /MSFTPSVC (FTP)
  • ADSI Class name from IIsWebServer (Web) to IIsFtpServer (FTP)
  • Account for SecureBindings which exist for HTTPS (Web) but not for FTP

And the exact same script now displays both FTP and Web site status. The new syntax is still pretty straight forward - I just added one new parameter to distinguish between querying FTP vs Web sites.

  • EnumSites.vbs - enumerates status for Websites on this server
  • EnumSites.vbs server1 - enumerates status for Websites on server1
  • EnumSites.vbs localhost FTP - enumerates status for Ftpsites on this server

Enjoy,

//David

 OPTION EXPLICIT

DIM strServer, strServerType, strServerMetaType
DIM objService

strServer = "localhost"
strServerType = "Web"
strServerMetaType = "W3SVC"

IF WScript.Arguments.Length >= 1 THEN
    strServer = WScript.Arguments( 0 )
END IF

IF WScript.Arguments.Length = 2 THEN
    strServerType = WScript.Arguments( 1 )

    IF UCASE( strServerType ) = "FTP" THEN
        strServerType = "Ftp"
        strServerMetaType = "MSFTPSVC"
    ELSE
        strServerType = "Web"
        strServerMetaType = "W3SVC"
    END IF
END IF

WScript.Echo "Enumerating " & strServerType & "sites on " & strServer & VbCrLf
SET objService = GetObject( "IIS://" & strServer & "/" & strServerMetaType )
EnumServersites objService


SUB EnumServersites( objService )
    DIM objServer, strBindings

    FOR EACH objServer IN objService
        IF objServer.Class = "IIs" & strServerType & "Server" THEN
            WScript.Echo _
                "Site ID = " & objServer.Name & VbCrLf & _
                "Comment = """ & objServer.ServerComment & """ " & VbCrLf & _
                "State   = " & State2Desc( objServer.ServerState ) & VbCrLf & _
                "LogDir  = " & objServer.LogFileDirectory & _
                ""

            ' Enumerate the HTTP bindings (ServerBindings) and
            ' SSL bindings (SecureBindings) for HTTPS only
            strBindings = EnumBindings( objServer.ServerBindings )

            IF strServerType = "Web" THEN
                strBindings = strBindings & _
                EnumBindings( objServer.SecureBindings )
            END IF

            IF NOT strBindings = "" THEN
                WScript.Echo "IP Address" & VbTab & _
                             "Port" & VbTab & _
                             "Host" & VbCrLf & _
                             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 & VbTab

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

        EnumBindings = EnumBindings & VbCrLf
    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