A common complaint from SharePoint 2007 was that pages would become slow over time. This was usually due to users closing web parts instead of deleting them from the page. Even though Microsoft fixed this problem in SharePoint 2010, some people might like to find closed web parts and delete them. The other day I came across this post by Phil Wicklund, and although the script is functional as-is, I decided to expand on it. Specifically, I made the following enhancements:

  • Searches all folders in a web, not just the root
  • Searches entire farm, not just one site
  • Fixed error when $pages is NULL by forcing pages to be an array
  • Deletes Web Parts more efficiently
  • Uses foreach instead of ForEach-Object (for performance, see here)

And here is the script!

Add-PSSnapin Microsoft.SharePoint.PowerShell

$webApps = Get-SPWebApplication

foreach ($webApp in $webApps)
{
    foreach ($site in $webApp.Sites)
    {
       foreach ($web in $site.AllWebs)
        {
            $pages = @($web.Files | ? {$_.Name -match ".aspx"})
            foreach ($folder in $web.Folders)
            {
                $pages += @($folder.Files | ? {$_.Name -match ".aspx"})
            }

            foreach ($page in $pages)
            {
                $webPartManager = $web.GetLimitedWebPartManager($page.ServerRelativeUrl, "Shared")

                $closedWebParts = @()
                foreach ($webPart in $webPartManager.WebParts | ? {$_.IsClosed})
                {
                    $closedWebParts += $webPart
                }
                foreach ($webPart in $closedWebParts)
                {
                    Write-Output "Deleting '$($webPart.Title)' on $($site.Url)/$($page.Url)"
                    $webPartManager.DeleteWebPart($webPart)
                }
            }
            $web.Dispose()
        }
        $site.Dispose()
   }
}

Comments (Closed)