Share via


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

Comments

  • Anonymous
    June 09, 2006
    David,

    This is outstanding!

    I would love to a use a few parts of your code, but I am not sure where to cut it out so it will still work.

    What I am looking to do is pull the strServer from AD OUs, the parts that of your code that would be a real help are the "Site ID = " and the  "LogDir  = " I wish to use these field as variables in a copy to move the logs out the dir on the server to some other place and use the Site ID as a variable to append to sub folders, which are made off the system name. I am set one everything but how to put the parts of your code into middle of the script as to pull those bits of info.

    I would also like try to run FTP and Web together as one script but two would work.

    Any help you could throw my way would be great.

    Thank you,
    David Brown




  • Anonymous
    June 09, 2006
    David - I suggest the following steps, which basically copies all script code and making three modifications - one addition and two bulk deletion of unneeded code.

    1. copy all of the code in the script as-is. You can remove the IF-blocks containing "WScript.Arguments.Length" if you want.

    2. Wrap two new FOR-loops around the following part of the script, one walking through the list of strServer from AD OUs, and the other for appropriate strServerMetaType values for FTP or Web:

    SET objService = GetObject( "IIS://" & strServer & "/" & strServerMetaType )
    EnumServersites objService

    3. Substitute all code inside the following IF-block in the code to use objServer.Name as ID and objServer.LogFileDirectory to append to sub folders and copy/move log files.

    IF objServer.Class = "IIs" & strServerType & "Server" THEN
       'Substitute all code inside this nested IF-block...
    END IF


    //David

  • Anonymous
    June 12, 2006
    David,

    Thank you for the reply.

    I will try to follow your steps, I am not very skilled at scripting so I hope this work out and fill needs I am trying to fill.

  • Anonymous
    June 19, 2006

    What would need to be changed to find the SMTP log locations?


    * Metabase configuration node from /W3SVC (Web) to /MSFTPSVC
    * ADSI Class name from IIsWebServer (Web) to IIsFtpServer (FTP)


    Thanks for any help, I am almost done with What I am trying to do.  You site has been a great help.

  • Anonymous
    June 19, 2006
    Does anyone see anything out of place in this chunk of code?

    Thanks



    '

    dim IISObj, IISSite

    ' WScript.echo ("Log file directories..." & strComputer )
    ' WScript.echo
    set IISObj = GetObject("IIS://"& strComputer &"/W3Svc")
    for each IISSite in IISObj
    if (IISSite.Class = "IIsWebServer") then
     WScript.echo IISSite.LogFileDirectory & "W3SVC" & IISSite.Name
     
    Set IISObj = GetObject("IIS://"& strComputer &"/MSFTPSVC")
    for each IISSite in IISObj
    if (IISSite.Class = "IIsFtpServer") Then
      WScript.echo IISSite.LogFileDirectory & "MSFTPSVC" & IISSite.Name
     
     
     strLocation = IISSite.LogFileDirectory
     DelLocation = IISSite.LogFileDirectory & "W3SVC" & IISSite.Name
    ' Wscript.echo strlocation
    ' Wscript.echo DelLocation
     
    End If

    '

  • Anonymous
    December 03, 2007
    Hi David, Your page came up when I did a search on how to use script to migrate an IIS site. Basically, what I need is to: gather all settings for a particular site, including things like host headers used write these settings to a newly-created site on the same server I don't want to ask someone else to do this for me - unless you've already written something which does it! - but would appreciate any pointers you can give on references for the methods that might be of interest. Many thanks

  • Anonymous
    December 03, 2007
    Re the above, please disregard - I've noticed that my Windows Administrator's Automation Toolkit has a chapter devoted to this... I simply haven't had time to look at it since I acquired it - until today! Thanks again,

  • Anonymous
    December 19, 2007
    I need to audit web servers in my domain, and would like to be able to connect to each server, and enumerate the virtual directories -- ultimately leading to a link to each web site hosted by the server.  Can this code be modified to get that information? Thanks.

  • Anonymous
    December 19, 2007
    Question: I need to audit web servers in my domain, and would like to be able to connect to each server,

  • Anonymous
    December 19, 2007
    The comment has been removed

  • Anonymous
    December 19, 2007
    Question: I need to audit web servers in my domain, and would like to be able to connect to each server

  • Anonymous
    January 19, 2008
    Has anybody modified this script, or could any one modify this script to write to a database or text file rather than a pop-up window. I am query 100s of servers, and I am not quite sure how to modify it accordingly. Actually I just need secure bindings and nothing else. Could anyone help me out? You can email me at bkilpatr@stewart.com if you like, or just post here.

  • Anonymous
    January 26, 2008
    Noticias externas - As documented in the blog entry, the first commandline parameter to the tool is the name of the remote server //David

  • Anonymous
    January 26, 2008
    Brody - No modifications needed. Launch this script with CSCRIPT.EXE Default scripting host in Windows is WSCRIPT.EXE, which uses a popup window for output. One can easily redirect output to a text file, and entering data into a database is likewise easy from the commandline. Those are tasks best done by the reader. //David

  • Anonymous
    February 20, 2008
    Does it work both on IIS 5.0 and 6.0 ??

  • Anonymous
    February 22, 2008
    Frits - why don't you try it and be positively surprised? :-) //David

  • Anonymous
    June 20, 2008
    David, I love your script. I really to output this info to text file instead of the screen. I saw that you said cscript would do the job but I can't get it working. Would it be possible for you to create a small script outputing one of the variables to a file. I could then figure out the rest. Thank you in advance. Chet

  • Anonymous
    June 21, 2008
    Chet Bliss - CSCRIPT Script.VBS > Filename.txt //David

  • Anonymous
    September 02, 2008
    David, Thank you for the response. My team is enumerating web site on thousands of servers and I can not guarantee that IIS would be installed on every team members computer. I am trying to use SWbemServices with your script and can not get it to work. Thanks Chet

  • Anonymous
    October 29, 2008
    Been looking all day for something like this. Just what I needed, thanks. -Felix

  • Anonymous
    November 21, 2008
    Davind, great piece of code! Thank you; very useful. Now... I need to find the physical path to any given Web site on a given machine that has IIS 5, 6 or 7 on it. So, using the site ID seems to be the way to go... But what property do I check for? Sorry, am not very well versed in finding IIS metadata and am unsure where to look... I can see that Server.MapPath is used in some cases in ASP... but I need to use vbscript. Thanks in advance! Harshini

  • Anonymous
    November 24, 2008
    The comment has been removed

  • Anonymous
    April 08, 2009
    Would be great to find a type library for these objects somewhere. I'm not a very variant kind of guy.  =) The Active DS IIS Extension Dll appears to be incomplete.

  • Anonymous
    June 07, 2010
    The comment has been removed

  • Anonymous
    July 23, 2011
    The comment has been removed

  • Anonymous
    July 23, 2011
    The comment has been removed

  • Anonymous
    March 19, 2014
    Hi David, how do I collect the base installation directory of the website, Leonard Leonard.lunardi@trescon.com.br