Share via


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

Comments

  • Anonymous
    October 27, 2005
    Nice work, thanks

  • Anonymous
    December 07, 2005
    This was just what I needed.

  • Anonymous
    January 31, 2006
    Thanks. This script saves me a lots of time.

  • Anonymous
    February 28, 2006
    The comment has been removed

  • Anonymous
    February 28, 2006
    Actually I can run the script locally on the server but not from my workstation.

    Levi

  • Anonymous
    February 28, 2006
    Levi - Make sure that IIS is actually installed on the machine you are trying to launch the script (the workstation).

    Since the GetObject() syntax is ADSI, it requires the IIS ADSI provider to be installed on both the local and remote machine... even if you are only trying to get a remote ADSI object.

    //David

  • Anonymous
    April 10, 2006
    I get a Type mismatch when I try to access the ServerBindings property.
    Any idea why?

  • Anonymous
    April 10, 2006
    Tony - Can you show the exact code snippet where you are trying to "access" the ServerBindings property that results in "Type mismatch".

    //David

  • Anonymous
    April 18, 2006
    Absolutely brilliant! I have a machine with over 50 websites on it each with multiplehost headers. This has saved me hours, thankyou VERY much!

  • Anonymous
    April 18, 2006
    The comment has been removed

  • Anonymous
    May 04, 2006
    The comment has been removed

  • Anonymous
    May 05, 2006
    Hung_Ngo - I suggest reading Microsoft's MSDN online for the information you want, especially Script Center, which contains tons of sample script code to do just about every action for many Microsoft products.

    I do not understand what you mean by "stop and start SSL service on a particular page" - please clarify what you are trying to do.

    //David

  • Anonymous
    May 05, 2006
    The comment has been removed

  • Anonymous
    May 10, 2006
    How do you get the output to a text file - instead of the gui pop screens?

    thanks

    Mike

  • Anonymous
    May 11, 2006
    Mike - Windows support running scripts in multiple "hosts" which may display output either in a console window or as popup dialogs.

    Default host is WSCRIPT, which shows popup dialogs.

    You want to use CSCRIPT, which shows output to console window and can be piped into a text file.

    Either:
    1. Launch the script one-time with CSCRIPT.EXE:
     CSCRIPT EnumWebsites.vbs
    2. Change the default script host to CSCRIPT with:
     CSCRIPT //h:cscript
     EnumWebsites.vbs

    //David

  • Anonymous
    June 08, 2006
    Thanks for this ... two questions:

    1. How could I do the same for FTP sites and ...

    2. How can I modify values for both?

  • Anonymous
    June 08, 2006
    I recently got a request to make a script to illustrate how to enumerate useful values from both Web...

  • Anonymous
    June 08, 2006
    The comment has been removed

  • Anonymous
    June 12, 2006
    David, the website is awesome. thanks for your effort and answering the kinds of IIS questions that dont seem to have been answered in the last 10 years.

    Am I missing something? There seems to be no iterators for active sessions in the IIS model. I can find the "active session count", but, can't find a collection of sessions that can be iterated. Does such a collection exist?

  • Anonymous
    June 12, 2006
    MikeMontana - there are no APIs to retrieve current runtime state, like "active sessions" in IIS. Technically, IIS has no idea about "sessions" - it only knows about requests and connections - so application frameworks like ASP/ASP.Net can offer such behavior, which is completely up to the individual frameworks.

    //David

  • Anonymous
    August 24, 2006
    how can i take (site id) in the (Comment) possision.

  • Anonymous
    September 13, 2006
    Great script. One thing tough. How can one add a listing of the Application Pool each site belongs to ?

  • Anonymous
    September 13, 2006
    ..and howto add a listing to the homedir folder path where the files for the site's located ?

  • Anonymous
    July 11, 2007
    very useful!!! well, any idea how I can get the same result by using asp.net code? Then I shall be able to access those information from "outside" of the server.

  • Anonymous
    July 11, 2007
    I guess I could use asp.net code to run VBScript too, but I do prefer, if it is possible, to use pure asp.net code to get the same result.

  • Anonymous
    December 19, 2007
    Hi David, I need get the latest created Site ID. The iisweb create a site with random large number, we don't want to use these number for site ID. Instead we want to use sequence number, for example, 1,2,3,4. We want to use script to get the largest sequence number among all the IIS web sites, then use createNewSite by passing this SITEID +1 into the parameters. Could you provide the script for us to find the latest created site ID? Thanks

  • Anonymous
    December 19, 2007
    The comment has been removed

  • Anonymous
    January 03, 2008
    This script leaves out gather any info on child VDir websites.

  • Anonymous
    January 05, 2008
    The comment has been removed

  • Anonymous
    January 10, 2008
    You're correct and my apologies then. I guess I've been posting on CodeProject too much.

  • Anonymous
    January 29, 2008
    what a wonderful tool. you rock!  thanks.

  • Anonymous
    February 07, 2008
    We just took over a company that had hundreds of websites on old NT4 boxes... This tool has saved us a huge amount of work... many thanks

  • Anonymous
    March 09, 2008
    I would like to allow my web designer to be able to add a Index.asp document to a website and then move it up to the top of the list.  I dont want them to use the IIS interface as it allows too much scope for messing up.   Anyone got any ideas?

  • Anonymous
    March 11, 2008
    Here is a convergence and alteration of the above script - that does a ping test first.  Ping-test example comes from here: http://www.scriptinganswers.com/vault/Registry/ the script below is nasty, and has has some hard coded paths which could easily be cleaned up by someone who needed to run it regularly... I just needed it to run once to collect all of the websites, siteid, and logfile path for about 200 web servers. 'begin Const HKEY_LOCAL_MACHINE = &H80000002 Const ForAppending = 8 DIM strServer DIM objWebService Dim objFSO, objFolder, objShell, objFile, objFSOText, strDirectory, strFile, objTextFile strDirectory = "c:tempsite_collection" strFile = "web_site_logdir_collection.csv" ' Grab computer names from a list and insert into the script Set objFSO = Wscript.CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("c:tempsite_collectionComputerList.txt") ' Create files for logging errors Set objNoPing = objFSO.CreateTextFile("c:tempsite_collectionNoPing.txt") Set objErrorLog = objFSO.CreateTextFile("c:tempsite_collectionErrorLog.txt") Set objFSO2 = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO2.OpenTextFile (strDirectory & strFile, ForAppending, True) ' Read through text stream Do Until objFile.AtEndOfStream strServer = Trim(objFile.ReadLine) On Error Resume Next 'Test to see if the computer is reachable by ping If IsAlive(strServer) = TRUE Then ' get IIS info SET objWebService = GetObject( "IIS://" & strServer & "/W3SVC" ) EnumWebsites objWebService If Error <> 0 Then objErrorLog.Writeline "Error on " & strServer & ":" & Err.Number & ", " & Err.Description End If ' Write a line to the leftovers file to be run against later ElseIf IsAlive(strServer) = FALSE Then objNoPing.Writeline strServer End If ' Loop through to next computer in textfile Loop ' At end of text stream, close open files objFile.Close objNoPing.Close objErrorLog.Close SUB EnumWebsites( objWebService )    DIM objWebServer, strSecureBind, strServerBind, strBindings, strOutput, strEnd, intLength    FOR EACH objWebServer IN objWebService        IF objWebserver.Class = "IIsWebServer" THEN            'WScript.Echo objWebserver.Name & ";" & objWebServer.ServerComment & ";" & State2Desc( objWebserver.ServerState ) & ";" & objWebServer.LogFileDirectory            strOutput = strServer & ";" & objWebserver.Name & ";" & objWebServer.ServerComment & ";" & State2Desc( objWebserver.ServerState ) & ";" & objWebServer.LogFileDirectory            ' Enumerate the HTTP bindings (ServerBindings) and            ' SSL bindings (SecureBindings)            strSecureBind = EnumBindings( objWebServer.SecureBindings )    strServerBind = EnumBindings( objWebServer.ServerBindings )            strOutput = strOutput & ";" & strServerBind & ";" & strSecureBind        objTextFile.WriteLine(strOutput) 'Wscript.Echo strOutput        END IF    NEXT END SUB ' =============================================================================================================================== Function IsAlive(strHost) ' Returns True if Host responds to ping ' strHost is a hostname or IP Const OpenAsASCII = 0 Const FailIfNotExist = 0 Const ForReading =  1 Dim objShell, objFSO, sTempFile, fFile  Set objShell = CreateObject("WScript.Shell")  Set objFSO = CreateObject("Scripting.FileSystemObject")    sTempFile = objFSO.GetSpecialFolder(2).ShortPath & "" & objFSO.GetTempName    objShell.Run "%comspec% /c ping.exe -n 2 -w 500 " & strHost & " >" & sTempFile, 0 , True  Set fFile = objFSO.OpenTextFile(sTempFile, ForReading, FailIfNotExist, OpenAsASCII)  Select Case InStr(fFile.ReadAll, "TTL=")         Case 0            IsAlive = False         Case Else            IsAlive = True    End Select    fFile.Close     objFSO.DeleteFile(sTempFile)    Set objFSO = Nothing    Set objShell = Nothing End Function 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 & ":"            EnumBindings = EnumBindings & ":" & strIP & ":" & strPort & ":" & strHost & ""        NEXT    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

  • Anonymous
    March 11, 2008
    P.S. to post above: the following would be the header for the .csv file created, if you needed to import it Server; Site ID ; Comment ; State ; LogDir ; Standard IP Address:Port:Host:; Secure IP Address:Port:Host:

  • Anonymous
    March 14, 2008
    The comment has been removed

  • Anonymous
    March 21, 2008
    Hi, thanks for the great script. However, I can't seem to get it running. When I run cscript siteslist.vbs I get access denied and a google search hasn't helped me. Even when I just run cscript I get an access denied. Can you point me in the direction of some solution? Thanks.

  • Anonymous
    March 21, 2008
    Nick - unfortunately, it sounds like you are in an environment which prevents users from running scripts, and I will not be able to help your circumvent your environment's security measures. //David

  • Anonymous
    April 30, 2008
    How do you enumerate the current list of IP Addresses on the server? The IIS Management snap-in does this of course, but I cannot find what method I would use to complete this action. The purpose would be so I can enumerate the list of available IPs on the server so when I use the server binding, I can populate a listbox/combobox for ip selection rather than ip entry. I hope you can point me in the right direction. Thanks and great article!

  • Peter
  • Anonymous
    May 13, 2008
    The comment has been removed

  • Anonymous
    May 13, 2008
    SAM - all of my scripts require IIS6 Metabase Compatibility to run on IIS7. This is because they use ADSI, which requires the IIS6 Metabase Compatibility feature on IIS7. There is a new WMI and COM provider for IIS7 but code for that is IIS specific. Depending on the concepts I am illustrating, I would use different APIs. For examples, websites/vdir/ISAPI have always existed and use classic API. While Modules/Handlers originate from IIS7 and only use IIS7-specific APIs. You can use APPCMD.EXE in %windir%System32inetsrv to do many of the common (but not all) configuration-related tasks. You will have to read the help to determine the syntax. //David

  • Anonymous
    June 20, 2008
    The comment has been removed

  • Anonymous
    June 21, 2008
    Michael - you need to run this script on machines with IIS installed in order to query remote machines with IIS installed, using ADSI. You won't be able to query IIS6-specific properties with ADSI from XP Pro 32bit -- for example, AppPoolId. In this case, you are querying common properties that exist both in IIS on XP and W2K3, so it is fine. //David

  • Anonymous
    June 24, 2008
    thankyou thankyou thankyou!!!!! this script is exactly what i needed to obtain site ID's for a site to then use in another script to set the SSL host headers.

  • Anonymous
    June 24, 2008
    I modified the script slightly for my purposes and thought i'd share. This asks for a website name and then uses David's script to locate the site identifier for that name. It then runs adsutil.vbs with that identifier to set the port 80 and port 443 site headers. i had to do this because the IIS Manager GUI doesn't have an option to set site headers for SSL !? Why, I have no idea... and then they go and provide us a cmd line script to do it, but that script requires the numeric site id, which is difficult to easily find out..  Hence thanks to David's code and a little bit of addition, I was able to script this nicely so any of our administrators could do it with ease. '---------------------------------------------------------------- '---- Set WebSite Headers.vbs ---- '   Written by Dave - 25.6.08 ' '   Code for interogating IIS metabase to obtain SiteName (site identifier) '   obtained from David Wang (http://blogs.msdn.com/david.wang) ' '   Script uses IIS Admin Script "adsutil.vbs" which must exist '   (installed by default with IIS 6.0) '---------------------------------------------------------------- OPTION EXPLICIT DIM CRLF, TAB DIM strServer, strSiteName, strRun DIM objWebService, objShell TAB  = CHR( 9 ) CRLF = CHR( 13 ) & CHR( 10 ) SET objShell = Wscript.CreateObject("Wscript.Shell") SET objWebService = GetObject( "IIS://" & strServer & "/W3SVC" ) strServer = "localhost" DO strSiteName = Inputbox("This script will edit the IIS metabase to include header bindings for port 80 and SSL port 443." & vbCrLf & vbcrlf & "Enter the IIS Website name" & vbCrLf & "eg. swanhill.munitec.com.au", "Set Website headers", "council.munitec.com.au") LOOP UNTIL strSiteName <> "council.munitec.com.au" if instr(strSiteName,".") < 1 then msgbox "Not a proper domain name - website name must be a fully qualified domain name" wscript.quit end if '------------------------ '-- run script to set headers EnumWebsitesSetHeader objWebService '-- print out web site info & new bindings EnumWebsites objWebService SUB EnumWebsitesSetHeader( objWebService )    DIM objWebServer, strBindings    FOR EACH objWebServer IN objWebService        IF objWebserver.Class = "IIsWebServer" THEN if ucase(objWebServer.ServerComment) = ucase(strSiteName) then strRun = "cscript.exe C:InetpubAdminScriptsadsutil.vbs set /w3svc/" &_ objWebServer.Name & "/SecureBindings " &_ """:443:" & strSiteName & """  " objShell.Run strRun, 0, True strRun = "cscript.exe C:InetpubAdminScriptsadsutil.vbs set /w3svc/" &_ objWebServer.Name & "/ServerBindings " &_ """:80:" & strSiteName & """  " objShell.Run strRun, 0, True end if        END IF    NEXT END SUB SUB EnumWebsites( objWebService )    DIM objWebServer, strBindings    FOR EACH objWebServer IN objWebService        IF objWebserver.Class = "IIsWebServer" THEN if ucase(objWebServer.ServerComment) = ucase(strSiteName) then         WScript.Echo _         "Site ID = " & objWebserver.Name & CRLF & _                "Server Comment = """ & objWebServer.ServerComment & """ " & CRLF & _ "State   = " & State2Desc( objWebserver.ServerState ) & CRLF & _                 ""            ' 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        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..."    CASE 2        State2Desc = "Started"    CASE 3        State2Desc = "Stopping..."    CASE 4        State2Desc = "Stopped"    CASE 5        State2Desc = "Pausing..."    CASE 6        State2Desc = "Paused"    CASE 7        State2Desc = "Continuing.."    CASE ELSE        State2Desc = "Unknown state"    END SELECT END FUNCTION

  • Anonymous
    June 26, 2008
    The comment has been removed

  • Anonymous
    August 06, 2008
    Excellent work. 2 seconds to get a complete listing - and that 2 seconds included the copying of the text and renaming the vbs file:-)

  • Anonymous
    September 15, 2008
    Hi David, Thanks for sharing the information. I have a requirement to get the "Physical Path" of a web site. In general its value for Default Web Site will be "%SystemDrive%inetpubwwwroot". What property name of  "IIsWebServer" should I use to get the "Physical Path" of a web site? GIRI

  • Anonymous
    September 17, 2008
    Giri - There is no such thing as "physical path" of a website. So, the property you are looking for does not exist. You can only retrieve the physical path of a certain URL, and you need to read the "Path" property of the "IIsWebVirtualDir" object to get that value. //David

  • Anonymous
    November 14, 2008
    I am able to get physical path of virtual directories from iis but not if i set websites at different ports instead of creating virtual directories. Please help..

  • Anonymous
    November 21, 2008
    Hello, How can we get properties of virtualdir under IIS://" & strServer & "/W3SVC/N/myspace ?

  • Anonymous
    November 24, 2008
    Xman - I suggest looking at how %SYSTEMDRIVE%InetpubAdminScriptsADSUTIL.VBS does it when you run:  CSCRIPT %SYSTEMDRIVE%InetpubAdminScriptsADSUTIL.VBS ENUM W3SVC/N/myspace //David

  • Anonymous
    December 25, 2008
    Advice me the script to list the website name, port number, host header, IP, SSL, and auth in all the application in the server..

  • Anonymous
    February 25, 2009
    This is awesome, it's saved me hours of time in the middle of a crisis. Thanks!

  • Anonymous
    April 22, 2009
    Hi David, your script is great! I have one question though, what if I have multiple servers to query, e.g. 100 servers to check and  not just the local machines, how do I modify the script to accomodate it?

  • Anonymous
    April 30, 2009
    The comment has been removed

  • Anonymous
    May 05, 2009
    The Script is awesome. Can someone get me a script which pulls up authentication for Default website and all other VDir's in IIS ?? Ratish

  • Anonymous
    May 27, 2009
    Hi Guys, Have edited David's script to include listing of home directory for website content per site and also output to a txt file. http://satchelmouth.wordpress.com/2009/05/28/script-to-list-important-details-for-all-websites-in-iis6/ ( I couldn't seem to post the entire script contents here, maybe a character limit? )

  • Anonymous
    May 28, 2009
    Hi All, My IIS 6 server has become a little bit of a mess and I'd like to update the ServerComment (IIS site name) from the metabase to match the primary host header value. Has anyone done that before? thanks darian

  • Anonymous
    June 07, 2009
    Excellent work. 2 seconds to get a complete listing - and that 2 seconds included the copying of the text and renaming the vbs file:-)

  • Anonymous
    June 22, 2009
    David: I'm trying to access the 'objServer.DefaultDoc' value(s).  I can retrieve the values but if I update the value (add/remove a document), the 'DefaultDoc' value remains unchanged. Any ideas on how to get the current values?

  • Anonymous
    July 06, 2009
    Hi David.  Thanks for the great blog.   This code returns a WMI 'Provider Load Failure' against an IIS7 server even with "IIS6 WMI Compatibility" installed.  But it will work if I add "IIS6 Metabase Compatibility".   So question #1 is 'Am I missing something?' And question #2 is 'How strongly should I bother resisting enabling IIS6 Metabase Compatibility -- is it that big of a deal?' Set objWMIService = GetObject("winmgmts:{authenticationLevel=pktPrivacy}!\servernamerootMicrosoftIISv2") Set colItems = objWMIService.ExecQuery("SELECT * FROM IIsApplicationPools_IIsApplicationPool", "WQL", &h10 + &h20) Result = "AppPools" & vbcrlf   For Each objItem In colItems      Result = Result & objItem.PartComponent & vbcrlf   Next WScript.Echo Result Thanks so much!

  • Anonymous
    July 10, 2009
    Excellent work. 2 seconds to get a complete listing - and that 2 seconds included the copying of the text and renaming the vbs file:-)

  • Anonymous
    August 01, 2009
    Hi David, Thanks for sharing the information. I have a requirement to get the "Physical Path" of a web site. In general its value for Default Web Site will be "%SystemDrive%inetpubwwwroot". What property name of  "IIsWebServer" should I use to get the "Physical Path" of a web site? GIRI

  • Anonymous
    August 01, 2009
    Set objWMIService = GetObject("winmgmts:{authenticationLevel=pktPrivacy}!\servernamerootMicrosoftIISv2") Set colItems = objWMIService.ExecQuery("SELECT * FROM IIsApplicationPools_IIsApplicationPool", "WQL", &h10 + &h20) Result = "AppPools" & vbcrlf  For Each objItem In colItems     Result = Result & objItem.PartComponent & vbcrlf  Next WScript.Echo Result Thanks so much!

  • Anonymous
    August 01, 2009
    Excellent work. 2 seconds to get a complete listing - and that 2 seconds included the copying of the text and renaming the vbs file:-)

  • Anonymous
    August 01, 2009
    SAM - all of my scripts require IIS6 Metabase Compatibility to run on IIS7. This is because they use ADSI, which requires the IIS6 Metabase Compatibility feature on IIS7. There is a new WMI and COM provider for IIS7 but code for that is IIS specific. Depending on the concepts I am illustrating, I would use different APIs. For examples, websites/vdir/ISAPI have always existed and use classic API. While Modules/Handlers originate from IIS7 and only use IIS7-specific APIs.

  • Anonymous
    August 03, 2009
    Thank u for the script.  I modified it a little bit to show the IP of the server. OPTION EXPLICIT DIM CRLF, TAB DIM strServer DIM objWebService DIM strcomputer DIM objWMIService DIM colItems DIM strCount DIM objitem DIM stripaddress DIM IP TAB  = CHR( 9 ) CRLF = CHR( 13 ) & CHR( 10 ) strcomputer = "." Set objWMIService = GetObject("winmgmts:" _    & "{impersonationLevel=impersonate}!&quot; & strComputer & "rootcimv2") Set colItems = objWMIService.ExecQuery _    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True") strCount = 1 For Each objitem in colitems    If strCount = 1 Then        strIPAddress = Join(objitem.IPAddress, ",")        IP = stripaddress        strCount = strCount + 1         ' wscript.echo IP    Else    End If next 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 _                IP & TAB & objWebserver.Name & TAB &objWebServer.ServerComment & TAB & State2Desc( objWebserver.ServerState )            ' Enumerate the HTTP bindings (ServerBindings) and            ' SSL bindings (SecureBindings)            strBindings = EnumBindings( objWebServer.ServerBindings ) & EnumBindings( objWebServer.SecureBindings )            IF NOT strBindings = "" THEN                ' WScript.Echo 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 My question, and i've searched high and low.   How do i grab the header names from under "website properties > website tab > Advanced button > Host Headers? I can't find anything in how to grab that.  We are consolidating our "similar sites" and the current incarnation of the script doesn't show the host headers on the sites we combined into one site.

  • Anonymous
    August 05, 2009
    Nevermind.. lol   in the modified script i made i inadvertantly took that part out.. nothing to see, move along... :)

  • Anonymous
    August 08, 2009
    Thanks for the script! Is there any way that I can receive the IP address of the IIS Server that is currently being used on my website? I have 2 IIs servers for the website and I'd like to know which was used when a user registers (a record is inserted  to the db) on my website.

  • Anonymous
    October 18, 2009
    David, thank you so much. We used the basis of your script to deploy to over 1K+ web servers as ASP page - this allows us to target a specific page in any web site and it will obviously provide us with the info for all hosted applications - made life so much simpler for us... i.e. server name, web site names, State, IP's, etc etc... Our code is below: 1.) Anonymous Authetication must be disabled on this asp file 2.) Integrated Windows Authentication must be enabled on this asp file. -- Start of Code -- <%@LANGUAGE=VBSCRIPT @ENABLESESSIONSTATE=False%&gt; <% Option Explicit %> <% Response.Buffer=True %> <% Response.Expires=0 %> <% Response.ExpiresAbsolute=Date-1%> <% Response.AddHeader "cache-control","private"%> <% Response.AddHeader "pragma","no-cache"%> <% '------- WWWinfo.asp script to obtain Server & WWW information ------- '------- obtain Server Name ------- Dim objNetwork Dim strServer Set objNetwork = CreateObject("WScript.Network") strServer = UCase(objNetwork.ComputerName) Set objNetwork = Nothing %> <table border="0" align="center" width="90%" style="font-family: Verdana; font-size: 12pt" > <tr>  <td align="center" colspan="9" background="./canvas.jpg"><img src="./logo.gif"></td> </tr> <tr>  <td bgcolor="#6699FF" align="center" colspan="9"><font color="#FFFFFF"><b>WEB SERVER : <% Response.Write UCase(strServer) %></b></font></td>       </tr> <tr>  <td align="center"><font size="1"><b>Site ID</b></font></td>  <td align="center"><font size="1"><b>Description</b></font></td>  <td align="center"><font size="1"><b>Site Dir</b></font></td>  <td align="center"><font size="1"><b>Log Dir</b></font></td>  <td align="center"><font size="1"><b>IP Address</b></font></td>  <td align="center"><font size="1"><b>TCP Port</b></font></td>  <td align="center"><font size="1"><b>SSL Port</b></font></td>  <td align="center"><font size="1"><b>Status</b></font></td> </tr> <% '------- obtain Server Name ------- DIM CRLF, TAB 'DIM strServer DIM objWebService DIM objWebServerRoot TAB  = CHR( 9 ) CRLF = CHR( 13 ) & CHR( 10 ) 'Response.Write "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 SET objWebServerRoot = getobject(objWebServer.adspath & "/root") %> <tr>  <td align="center"><font size="1"><% Response.Write "W3SVC" & (objWebserver.Name) %></font></td>  <td align="center"><font size="1"><% Response.Write (objWebServer.ServerComment) %></font></td>  <td align="center"><font size="1"><% Response.Write (objWebserverRoot.Path) %></font></td>  <td align="center"><font size="1"><% Response.Write (objWebServer.LogFileDirectory & "W3SVC" & objWebserver.Name) %></font></td>  <td align="center"><font size="1"><% Response.Write (EnumIP (objWebServer.ServerBindings)) %></font></td>  <td align="center"><font size="1"><% Response.Write (EnumSrvPort (objWebServer.ServerBindings)) %></font></td>  <td align="center"><font size="1"><% Response.Write (EnumSrvPort (objWebServer.SecureBindings)) %></font></td>  <td align="center"><font size="1"><% Response.Write (State2Desc( objWebserver.ServerState )) %></font></td> <% '------- Enumerate Bindings -------            strBindings = EnumBindings( objWebServer.ServerBindings ) & _                          EnumBindings( objWebServer.SecureBindings )            IF NOT strBindings = "" THEN            END IF        END IF set objWebServerRoot=nothing    NEXT END SUB '------- Strip IP Bindings ------- FUNCTION EnumIP( objBindingList )    DIM x, strIP    DIM reBinding, reMatch, reMatches    SET reBinding = NEW RegExp    reBinding.Pattern = "([^:]):([^:]):(.)"    FOR x = LBOUND( objBindingList ) TO UBOUND( objBindingList)        SET reMatches = reBinding.Execute( objBindingList( x ) )        FOR EACH reMatch IN reMatches            strIP = reMatch.SubMatches( 0 )            IF strIP = "" THEN strIP = "All Unassigned"            IF LEN( strIP ) < 8 THEN strIP = strIP & TAB            EnumIP = EnumIP & strIP        NEXT        EnumIP = EnumIP & CRLF    NEXT END FUNCTION '------- Strip PORT Bindings ------- FUNCTION EnumSrvPort( objBindingList )    DIM y, strPort    DIM reBinding, reMatch, reMatches    SET reBinding = NEW RegExp    reBinding.Pattern = "([^:]):([^:]):(.)"    FOR y = LBOUND( objBindingList ) TO UBOUND( objBindingList )        SET reMatches = reBinding.Execute( objBindingList( y ) )        FOR EACH reMatch IN reMatches            strPort = reMatch.SubMatches( 1 )            IF strPort = "" THEN strPort = ""            EnumSrvPort = EnumSrvPort & strPort        NEXT        EnumSrvPort = EnumSrvPort & CRLF    NEXT END FUNCTION '------- Strip HOST Bindings ------- FUNCTION EnumBindings( objBindingList )    DIM z, strIP, strPORT, strHost    DIM reBinding, reMatch, reMatches    SET reBinding = NEW RegExp    reBinding.Pattern = "([^:]):([^:]):(.)"    FOR z = LBOUND( objBindingList ) TO UBOUND( objBindingList )        ' objBindingList( i ) is a string looking like IP:Port:Host        SET reMatches = reBinding.Execute( objBindingList( z ) )        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 '------- DEFINE IIS STATUS ------- FUNCTION State2Desc( nState )    SELECT CASE nState    CASE 1        State2Desc = "Starting"    CASE 2        State2Desc = "Started"    CASE 3        State2Desc = "Stopping"    CASE 4        State2Desc = "Stopped"    CASE 5        State2Desc = "Pausing"    CASE 6        State2Desc = "Paused"    CASE 7        State2Desc = "Continuing"    CASE ELSE        State2Desc = "Unknown state"    END SELECT END FUNCTION %> -- End of Code --

  • Anonymous
    November 16, 2009
    Wow, talk about doing things the hard way.  A few tips, David (if you haven't figured these out in the past four years): vbTab is a VB constant - you don't need TAB vbCrLf is a VB constant - you don't need CRLF If Not strBindings = "" Then   ... is easier said: If strBindings <> "" Then That reBinding regular expression isn't needed.. try Split(objBindingList(i),":") ... results in an array as well but more efficient and less confusing Adding & "" to the end of the EnumBindings = EnumBindings.. statement is pointless Otherwise, nice job on a working prototype.

  • Anonymous
    January 23, 2010
    David, Please share the script which should display the home folder path along with full information about the Virtual Directories configured in the website as well. This script is also not displaying the Application pool configured for the website.

  • Anonymous
    February 07, 2010
    '  Enumerate Servers in the domain, which is having IIS '  Same code given by DAVID '  Can you please evaluate '  --------------------------------------------------------- Set objAdRootDSE = GetObject("LDAP://RootDSE") Set objRS = CreateObject("adodb.recordset") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile("./IIS_Site_list.txt",2) Set WshNetwork = WScript.CreateObject("WScript.Network") strLhost = WshNetwork.ComputerName  varConfigNC = objAdRootDSE.Get("defaultNamingContext")  strConnstring = "Provider=ADsDSOObject"  strWQL = "SELECT * FROM 'LDAP://" & varConfigNC & "' WHERE objectCategory= 'Computer' and OperatingSystem = 'WindowsServer'"  objRS.Open strWQL, strConnstring  Do until objRS.eof 'WSCRIPT.ECHO "tEST" Set objServer = GetObject(objRS.Fields.Item(0)) strServerName = objServer.CN strOperatingSystem = objServer.OperatingSystem Set cPingResults = GetObject("winmgmts:{impersonationLevel=impersonate}//" & _ strLhost & "/root/cimv2"). ExecQuery("SELECT * FROM Win32_PingStatus " & _ "WHERE Address = '" + strServerName + "'") For Each oPingResult In cPingResults If oPingResult.StatusCode = 0 Then objfile.write strServerName & " is running " & strOperatingSystem & " Reachable" Set objWMIService = GetObject("winmgmts:&quot; & strservername & "rootcimv2") Set colServices = objWMIService.ExecQuery ("Select * from Win32_Service where Name Like '%IIS%'") IF colServices.Count = 0 Then objFile.Write ",IIS is not installed." objfile.writeline Else SET objWebService = GetObject( "IIS://" & strServername & "/W3SVC" ) FOR EACH objWebServer IN objWebService IF objWebserver.Class = "IIsWebServer" THEN            objFile.write "," & objWebserver.Name & "," & objWebServer.ServerComment & "," & _            State2Desc( objWebserver.ServerState ) & "," & objWebServer.LogFileDirectory             strBindings = EnumBindings( objWebServer.ServerBindings ) & _                           EnumBindings( objWebServer.SecureBindings )             IF NOT strBindings = "" THEN                 objFile.Write( strBindings )             END IF objfile.writeline         END IF     NEXT 'objFile.WriteLine '(strText) End If Else objFile.writeLine strServerName & " is running " & strOperatingSystem & " NOT Reachable" 'objfile.Writeline end if Next objRS.movenext Set objServer = Nothing    Loop  objRS.close Set objRS = Nothing Set objAdRootDSE = Nothing wscript.echo "Mission accomplished..." '-------------------------------------------------------------- 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 & "," & _                           strPort & "," & _                           strHost & "," & _                           ""        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

  • Anonymous
    February 09, 2010
    The comment has been removed

  • Anonymous
    June 16, 2011
    Is it possible to do this with WMI???

  • Anonymous
    September 16, 2014
    The comment has been removed