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):
- IIS ADSI Object Model Diagram (top-level view of the names and relations of various IIS administration objects).
- Documentation for IIsWebServer object (documentation for the IIsWebServer object, which is most pertinent to this question. You can find documentation for the other objects nearby).
- Script Center (lots of script snippets, but not a whole lot of hand-holding explanations)
- Simple script tool to edit IIS LIST objects
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, thanksAnonymous
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 removedAnonymous
February 28, 2006
Actually I can run the script locally on the server but not from my workstation.
LeviAnonymous
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.
//DavidAnonymous
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".
//DavidAnonymous
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 removedAnonymous
May 04, 2006
The comment has been removedAnonymous
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.
//DavidAnonymous
May 05, 2006
The comment has been removedAnonymous
May 10, 2006
How do you get the output to a text file - instead of the gui pop screens?
thanks
MikeAnonymous
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
//DavidAnonymous
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 removedAnonymous
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.
//DavidAnonymous
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? ThanksAnonymous
December 19, 2007
The comment has been removedAnonymous
January 03, 2008
This script leaves out gather any info on child VDir websites.Anonymous
January 05, 2008
The comment has been removedAnonymous
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 thanksAnonymous
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 FUNCTIONAnonymous
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 removedAnonymous
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. //DavidAnonymous
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 removedAnonymous
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. //DavidAnonymous
June 20, 2008
The comment has been removedAnonymous
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. //DavidAnonymous
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 FUNCTIONAnonymous
June 26, 2008
The comment has been removedAnonymous
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? GIRIAnonymous
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. //DavidAnonymous
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 //DavidAnonymous
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 removedAnonymous
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 ?? RatishAnonymous
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 darianAnonymous
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? GIRIAnonymous
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}!" & 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%> <% 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:" & 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 FUNCTIONAnonymous
February 09, 2010
The comment has been removedAnonymous
June 16, 2011
Is it possible to do this with WMI???Anonymous
September 16, 2014
The comment has been removed