SharePoint Closed WebParts Slowing You Down? Migrating from SharePoint 2007 to 2010 and Can't Find an Easy Way to Resolve (preupgradecheck) Findings? PowerShell's Got Your Back!

Performance is a concern of every system administrator, unless you're an Information Assurance kind of guy and then you'd probably just assume see the server switched off (just a bit of a nudge). If SharePoint is your poison, watch out for Closed WebParts throughout your site.

Closed WebParts are still attached to your page and are temporarily hidden, but they still load when the page loads. If there are a number of them, or any with Fatal Errors, you're unnecessarily impacting page load times and probably filling your logs with errors that are difficult to track down. Worse yet, if you plan a migration from SharePoint 2007 to 2010 and run the preupgradecheck STSADM command, you'll find yourself with a list of potential upgrade problems and no clear path to resolve them.

The handy PowerShell script below can help with both. It will iterate through all of the web applications on your server and the pages at the root of each site (it doesn't look at pages in libraries, which could also be an issue) and deletes closed WebParts as well as reporting WebParts that themselves are reporting a Fatal Error.

# Load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal") > $null

$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local;
$services = @($farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]})

foreach ($service in $services) {
    foreach ($app in $service.WebApplications) {
        foreach ($site in $app.Sites) {
            if (!$site.ServerRelativeUrl.Contains("ssp/")) {
                foreach ($currentWeb in $site.AllWebs) {
                    $pages = $currentWeb.Files | Where-Object {$_.Name -match ".aspx"}
                    foreach ($currentPage in $pages) {
                        Write-Host "Analyzing Page $($currentPage.ServerRelativeUrl)."
                        
                        if ($currentPage.CheckedOutByUser -ne $null) {
                            $currentPage.CheckIn("Administratively Checked-In");
                        }
                        
                        $webPartManager = $currentWeb.GetLimitedWebPartManager($currentPage.ServerRelativeUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
                        $closedWebparts = New-Object System.Collections.ArrayList
                        
                        foreach($webpart in $webPartManager.WebParts) {
                            if($webpart.IsClosed) {
                                $closedWebparts.add($webpart)
                            }
                        }
                        
                        foreach($webpart in $closedWebparts) {
                            Write-Host "Deleting closed webpart $($webpart.Title)"
                            $webPartManager.DeleteWebPart($webpart)
                        }
                    }
                    $currentWeb.Dispose()
                }
            }
            $site.Dispose()
        }
    }
}

Update: This PowerShell script is now maintained in my blog-code repository on GitHub. You can find the full script and documentation in the /PowerShell-SP-Cleanup directory.

Author’s Note: This article reflects my personal professional experience and opinions. While my insights are informed by my professional history, these views are my own and do not represent the official position of my former employer.

About the Author: Jacob Marks is an engineering leader with over 20 years of experience, including a decade at Amazon Web Services (AWS) where he led teams in EC2 Core Platform and the development of the AWS Payment Cryptography service.

Labels

.NET .NET 10 .NET 3.5 Active Directory AD DS Adoption AI AI coding AI Ethics AI Hype Alerts Amazon Cognito Amazon DLM Amazon Q Anthropic AppDomain Architecture Artificial Intelligence Asia Pacific Sydney ASP.net ASPxGridView Audit Readiness Auto Recovery Automation AWS AWS Certified AWS Lambda AWS Payment Cryptography AWS SDK AWS Security Specialty Azure Azure DevOps Server Backup BIG-IP C# Career Growth Cartes Bancaires CB Certificate Bundle Certification Claude Cloud Cloud Certification Cloud Hosting Cloud Security CloudWatch CLR Content Query Cost Optimization Credentials CyberChef Database Defense Industry Deloitte Developer Tools Developers DevEx DevExpress DevOps DISA Disk Space DISM Distributed Systems DoD DoD CC SRG DUKPT EBS EC2 Engineering Engineering Leadership Engineering Management EnPasFltV2 Enterprise Event Receiver Exam F5 Federal IT FedRAMP Fintech FISMA GAC Generative AI GitHub gMSA GovCloud Government Compliance GridView Hardware Security Modules HSM IAM Identity Management IIS Infra Infrastructure as Code IT Tools Jacob Marks JavaScript jQuery Lambda Leadership Linqpad LLM lsass.exe LTM Memory Optimization Mentorship Microsoft Migration Multi-Region Keys NACL Native AOT Network Architecture Networking NIST ODBC Open Source Payment Cryptography Payments PCI Compliance Performance Platform Platform Architecture Power Tools PowerShell Python re:Invent Reachability Analyzer Redshift Relationships List Replace Root Volume SAA-C00 SAP-C00 Security Security Group Serverless SES SharePoint SharePoint 2010 Site Reliability SMTP Snapshot Software Engineering Solutions Architect Solutions Architect Professional SP 2007 SPAWAR SSL STIG Storage Strategy Sydney SysAdmin Team Foundation Server Team Utilities Tech Industry Technical Depth Technology TFS Tools Troubleshooting Upgrade Visual Studio VPC VPC Flow Logs Web Development WebPart WinDirStat Windows Server Windows Server 2025 WinForms