SharePoint 2007 SiteMap Script

 

Microsoft SharePoint 2007 logo

I’ve had to dig up some PS scripts from my SP2007 days and I thought I’d share. Here’s a script that will crawl all Web Apps in a farm and will output metadata into an xml file for import into your favorite tool, like Excel.

The script will list web apps, site collections, webs, SPusers with full control privileges, content database names and sizes for each. Run it on any SP2007 web front end.

This is useful if you don’t have any other 3rd party migration or assessment tools installed in your environment.

 #SiteMap.ps1
#Mario Brandan, Regional Architect, Microsoft
#Script targets a SharePoint 2007 farm and will output a structured SiteMap.xml file that
#will list all web apps, site collections and webs, along with webs owners for webs that 
#have broken inheritance as well as those that inherit permissions.

#Run this locally on any front end
#Ensure the account has at least "Full Read" permissions on ever Web Application policy in
#Central administration.

#v3
#Added Db Size, Name for Site Collection node
#Added DisplayName, and Email attributes for FullControlUser node

clear-host

#Sp2k7 way of loading assembly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal")

#this doesn't work in the SP2k7 farm, probably because get-variable isn't there.
#$invocation = (Get-Variable MyInvocation).Value
#$path = Split-Path $invocation.MyCommand.Path 
#$filePath = "{0}\SiteMap.xml" -f $path

#Hard code the output file path
$filePath = "C:\dev\SiteMap.xml"
#Create the output file in xml format.
$xtw = New-Object System.Xml.XmlTextWriter($filePath, $null)

#Vars to be used in finding Full Control users
$groupNameWildcard = "Owners"
$existingRole = "Full Control"

#Make it readable
$xtw.Formatting = 'Indented'
$xtw.Indentation = 1
$xtw.IndentChar = "`t"

$xtw.WriteStartDocument()
#xsl
#$xtw.WriteProcessingInstruction("xml-stylesheet", "type='text/xsl' href='style.xsl'")

$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local;

$xtw.WriteStartElement("Farm")
$xtw.WriteAttributeString("FarmVersion", $farm.Version.ToString())

$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]}

Write-Host "Crawling all Web Apps and creating site map..."

foreach ($websvc in $websvcs) {
    foreach ($webapp in $websvc.WebApplications) {
        $xtw.WriteStartElement("WebApplication")
        $xtw.WriteAttributeString("WebAppName", $webApp.Name)
        $xtw.WriteAttributeString("WebAppAppPool", $webApp.ApplicationPool.Name)
        foreach ($site in $webApp.Sites){
            $xtw.WriteStartElement("SiteCollection")
            $xtw.WriteAttributeString("SiteCollectionUrl", $site.ServerRelativeUrl)
            $xtw.WriteAttributeString("SiteCollectionOwner", $site.Owner)
            #Get the Content Database.
            #Can't call $site.ContentDatabase directly due to non CLS-compliant type.
            #Retrieve the handle to the property using reflection instead.
            $cdbProperty = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("DisplayName")
            $xtw.WriteAttributeString("ContentDb", $cdbProperty.GetValue($site.ContentDatabase, $null))
            
            $cdbProperty = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("DiskSizeRequired")
            $xtw.WriteAttributeString("ContentDbSizeGb", ($cdbProperty.GetValue($site.ContentDatabase, $null))/1024/1024/1024)
            foreach($web in $site.AllWebs){
                Write-Progress -Activity "Crawling..." -Status $web.url
                $xtw.WriteStartElement("Web")
                $xtw.WriteAttributeString("WebUrl", $web.Url)
                
                if ($web.HasUniquePerm -and $web.AssociatedOwnerGroup -ne $null){
                    $xtw.WriteAttributeString("HasUniquePermissions", "True")
                    $fullControlRoleDef = $web.RoleDefinitions["Full Control"]
                    foreach($roleAssignment in $web.RoleAssignments){
                        if($roleAssignment.RoleDefinitionBindings.Contains($fullControlRoleDef)){
                            $principal = $roleAssignment.Member
                            if ($principal.GetType() -eq [Microsoft.SharePoint.SpGroup]){
                                foreach($fullControlUser in $principal.Users){
                                    $xtw.WriteStartElement("FullControlUser")
                                    $xtw.WriteAttributeString("Name", $fullControlUser.Name)
                                    $xtw.WriteAttributeString("LoginName", $fullControlUser.LoginName)
                                    $xtw.WriteAttributeString("Email", $fullControlUser.Email)
                                    $xtw.WriteEndElement()
                                }#foreach FullControlUser
                            }#if the principal is an SpGroup
                            else{
                                #the principal is a user
                                $fullControlUser = $principal.Member
                                $xtw.WriteStartElement("FullControlUser")
                                $xtw.WriteAttributeString("LoginName", $fullControlUser.LoginName)
                                $xtw.WriteAttributeString("Email", $fullControlUser.DistributionGroupEmail)
                                $xtw.WriteEndElement()
                            }#else                            
                        }#if Full Control principal
                    }#foreach RoleAssignment
                }#if uniquePermissions
                else{
                    $xtw.WriteAttributeString("HasUniquePermissions", "False")
                }
                $xtw.WriteEndElement()#Web
            }
            $xtw.WriteEndElement() #Site
        }
        $xtw.WriteEndElement() #WebApp
    }
}
$xtw.WriteEndElement()
$xtw.WriteEndDocument()
$xtw.Flush()
$xtw.Close()
#$msg = "Site Map created at {0}" -f $filePath
$msg = "Site Map created at " + $filePath
write-host $msg
write-host "Import into an Excel PivotTable for analysis"