Recursively listing all MOSS Site Collections and Sub Sites

by praveen 8/16/2008 3:06:54 PM

One of the painful tasks for a MOSS Admin is to make a list of all site-collections, sub-sites and nested sites. If you have allowed your customers to create their own sub-sites off a site collection or root site, it can turn out to be a really tough trying to create a list of all those. Our production engineering team came across the exact same problem. Recently they were planning to migrate the production data to another Test server to do some testing. While planning this, we realized that there were a lot of sub-sites etc on the production environment which were redundant or obsolete where no one was using them. So we planned to get rid of those and needed a comprehensive list of everything that was ever created or maintained in production environment. Since I have been playing with the the ever famous "stsadm" command, I offered to help them out by writing a script so we can view this in a neat and clean form like excel.

I am new to MOSS and still finding my way around, so I started off with first looking at the command output. As any good MOSS Admin would know there are two commands we can use to list site collections or sites. For site collections we can use the following command.

stsadm.exe -o enumsites -url <the root http url>

and the output looks like

 <Sites Count="4">
  <Site Url="http://pravmoss" Owner="DOMAIN\praveen" SecondaryOwner="DOMAIN\rahul" ContentDatabase="WSS_Content" StorageUsedMB="1003.1" StorageWarningMB="0" StorageMaxMB="0" />
  <Site Url="http://pravmoss/sitecol" Owner="DOMAIN\vignesh" ContentDatabase="WSS_Content" StorageUsedMB="2.4" StorageWarningMB="0" StorageMaxMB="0" />
  <Site Url="http://pravmoss/MySite" Owner="NT AUTHORITY\network service" SecondaryOwner="DOMAIN\praveen" ContentDatabase="WSS_Content" StorageUsedMB="0.3" StorageWarningMB="0" StorageMaxMB="0" />
  <Site Url="http://pravmoss/pedia" Owner="DOMAIN\praveen" SecondaryOwner="DOMAIN\rahul" ContentDatabase="WSS_Content" StorageUsedMB="2.5" StorageWarningMB="0" StorageMaxMB="0" />
</Sites>

whereas for looking up sub-sites we can use the following command line

stsadm.exe -o enumsubwebs -url <the root http url>

and the output looks like (if you pass the site collection URL http://pravmoss/pedia here)

<Subwebs Count="6">
  <Subweb>http://pravmoss/pedia/Docs</Subweb>
  <Subweb>http://pravmoss/pedia/mysite</Subweb>
  <Subweb>http://pravmoss/pedia/News</Subweb>
  <Subweb>http://pravmoss/pedia/Reports</Subweb>
  <Subweb>http://pravmoss/pedia/SearchCenter</Subweb>
  <Subweb>http://pravmoss/pedia/SiteDirectory</Subweb>
</Subwebs>

As you can see the output is simple XML. So if I can use any XML parser like XML DOM for example, I can load the output into an object and get the values and attributes. While writing the script I had to use recursion since the second output for the "subwebs" is only 1 level deep. So for example, if there were any other sub-sites under http://pravmoss/pedia/mysite from the output above, I will need to run the enumsubwebs command again on that URL to list out the subwebs and the output will look like...

<Subwebs Count="1">
  <Subweb>http://pravmoss/pedia/mysite/mynewsite</Subweb>
</Subwebs>

The script shown below is not very efficient since I am creating 3 different DOM objects and loading separate XML string output to that. If ever I come back to this, I will try and post a more cleaner script with updates.

So here is the complete script....

 

Option Explicit
Const STSADM_PATH ="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm"
Const ROOT_URL = "http://pravmoss/"
Const FILE_NAME = "D:\listofsites.xml"
 
Dim objShell, objExec, objXml, objXml2,objXml3, objSc,objFso, objFile, objWeb
Dim strResult, strSubResult, strUrl, strCmd, strOwner, strXML
 
'Retrieves all site collections in XML format.
 
WScript.Echo "Creating shell object and calling root enumsites command"
 
Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec(STSADM_PATH & " -o enumsites -url " & ROOT_URL)
 
strResult = objExec.StdOut.ReadAll
 
 
'Load XML in DOM document so it can be processed.
 
WScript.Echo "Loading XML File"
Set objXml = CreateObject("MSXML2.DOMDocument")
Set objXml2 = CreateObject("MSXML2.DOMDocument")
Set objXml3 = CreateObject("MSXML2.DOMDocument")
 
objXml.LoadXML(strResult)
 
WScript.Echo "Creating File System Object"
'Create the FileSystemObject and write to file.
Set objFso = CreateObject("Scripting.FileSystemObject")
 
if objFso.FileExists(FILE_NAME) then
    objFso.DeleteFile FILE_NAME, True
end if
 
set objFile = objFso.CreateTextFile(FILE_NAME, True)
 
'Loop through each site collection and call enumsubwebs to get the child URL's.
 
objFile.WriteLine("<ROOT>")
For Each objSc in objXml.DocumentElement.ChildNodes
    strUrl = objSc.Attributes.GetNamedItem("Url").Text
    strOwner = objSc.Attributes.GetNamedItem("Owner").Text
    strCmd = STSADM_PATH & " -o enumsubwebs -url """ + strUrl + """"
 
    Set objExec = objShell.Exec(strCmd)
    strResult = objExec.StdOut.ReadAll
    
    objFile.WriteLine("<SITECOLLECTION SiteCollectionURL='" & strUrl & "' Owner = '" & strOwner & "'>")
    objFile.WriteLine(strResult)
    WScript.Echo "Traversing the sub Webs..."
    call GetSubSites(strResult)
    objFile.WriteLine("</SITECOLLECTION>")
 
 
Next
objFile.WriteLine("</ROOT>")
 
set objFile = nothing
set objFso = nothing
set objXml = nothing
set objXml2 = nothing
set objXml3 = nothing
set objExec = nothing
 
WScript.Echo "File created"
 
sub GetSubSites(strResult)
objXml2.LoadXML(strResult)
for Each objWeb in objXml2.DocumentElement.ChildNodes
    strCmd = STSADM_PATH & " -o enumsubwebs -url """ + objWeb.text + """"
    Set objExec = objShell.Exec(strCmd)
    strResult = objExec.StdOut.ReadAll
 
    objXml3.LoadXML(strResult)
    if objXml3.DocumentElement.Attributes.GetNamedItem("Count").Text <> "0" Then
        objFile.WriteLine(strResult)
        WScript.Echo strResult
        call GetSubSites(strResult)
    end if
next
end sub
 
 

For running this, just copy paste the content to notepad and save it as a VBS file like for example, you can call it "ListAllMossSites.vbs" and then change the constants at the top to point to the path where your stsadm is located, URL for your root url and file name path to the place where you want to dump the file. Then run this from command prompt with a simple command like

cscript.exe ListAllMossSites.vbs

You can straight open the XML file in Excel and then filter on the site collection of your choice. Here is a sample screenshot of how this looks.

 

mosssites

Hope that helps!!!

Tags: , , ,

Code Snippet | Download | MOSS | Tips and Tricks

blog comments powered by Disqus

Comments


Who is Rahul?

Rahul

He works for Microsoft and likes Software & Gadgets!

He shares some interesting notes here while working with stuff that excites him.

Disclaimer

The opinions expressed herein are our own personal opinions and do not represent our employer's view in any way.
© Copyright 2014, Rahul Soni