Closed Web Parts in SharePoint – How to Find, Restore and Delete?
Closed Web Parts? What are they?
When users don’t need a particular web part on the page, they click on Edit drop down from the Web Part Menu, and choose “Close” instead of Delete. They prefer Close rather than Delete which is obvious!
Technically, When you close a Web Part, It doesn’t appear on the screen. But still running on the background and eating up the resources. It’s a best practice to delete the closed web parts. Because closed Web parts take up the memory and could cause an impact on performance.
How to Find closed web parts from SharePoint Interface?
How to find closed Web Parts? Open the Web Part page in Web Part Maintenance Mode (Just append ?contents=1 at the end in address bar). E.g. https://SharePoint.com/sites/sales/default.aspx?contents=1 and look for “No” value under Open on Page? column.
How to Delete Closed Web Parts using SharePoint Interface?
From the Web Part Maintenance Mode, choose the web parts which are in closed mode (Open on Page? column value “No”) and click on “Delete” from the Toolbar.
How to Stop Users from Closing a Web Part? Simple! Go to the web part properties, In the Advanced tab Disable the “AllowClose” check-box!
How to Restore Closed Web Parts using SharePoint Interface?
Accidental close of web parts may happen while you edit web part pages. Here is how to Restore closed web parts.
- Go to Site Actions >> Edit Page
- Click on the “Add a Web Part” link
- Scroll down and select “Closed Web Parts” (In MOSS 2007, Go to Advanced Web Part gallery and options)
- Once you click, it will show all the web part which are closed on this page.
- Choose the web parts and click on “Add” to bring closed web part to the page.
To delete a closed web part, Restore it first and then delete it!
How to Find and Delete Closed Web Parts With PowerShell?
Well, If it’s a single page, We can use a web part maintenance page to delete closed web parts. But for the whole site, it’s cumbersome. The closed web parts list can be retrieved by reading SharePoint Content Databases directly! But as per Microsoft’s Advice let’s not do it. Let’s use PowerShell instead. This script will create a CSV file for logging Pages and closed web parts before deleting it.
#Add SharePoint Snap-in
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$OutputReport ="C:\ClosedWebParts.csv"
$SiteURL="https://intranet.crescent.com"
#Write Header to CSV File
"Web Part Name,Site URL, Page URL" | out-file $OutputReport
#Get all Webs
#$WebsColl = Get-SPWebApplication | Get-SPSite -Limit All | Get-SPWeb -Limit All
$WebsColl = Get-SPSite $SiteURL | Get-SPWeb -Limit All
#Iterate through webs
foreach ($Web in $WebsColl)
{
write-host "Processing Web:"$Web.URL
#Get All Pages from site's Root into $AllPages Array
$AllPages = @($web.Files | Where-Object {$_.Name -match ".aspx"})
#Search All Folders for Pages
foreach ($Folder in $web.Folders)
{
#Add the pages to $AllPages Array
$AllPages += @($Folder.Files | Where-Object {$_.Name -match ".aspx"})
}
#Iterate through all pages
foreach($Page in $AllPages)
{
$WebPartManager = $web.GetLimitedWebPartManager($Page.ServerRelativeUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
#Array to Hold Closed Web Parts
$ClosedWebParts = @()
foreach ($webPart in $webPartManager.WebParts | Where-Object {$_.IsClosed})
{
$Result = "$($webpart.Title),$($web.Url),$($page.Url)"
Write-Host "Found a Closed Web Part: "$Result -f Green
$Result | Out-File $OutputReport -Append
$ClosedWebParts += $webPart.ID
}
#If the closed web part is found
If($ClosedWebParts)
{
#Checkout if required
if ($Page.RequiresCheckout)
{
if ($Page.CheckOutStatus -ne "None")
{
write-host "Overriding Checkout..."
$Page.UndoCheckOut()
}
$Page.CheckOut()
}
#Remove the web part from page
foreach ($WebPart in $ClosedWebParts)
{
Write-Host "Deleting closed web part at $($web.Site.Url)/$($page.Url)"
$WebPartManager = $Page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$WebPartManager.DeleteWebPart($WebPartManager.webParts[$webPart])
}
#Check-in
if ($Page.CheckOutStatus -ne "None")
{
$Page.CheckIn("Deleted web part")
$Page.Publish("Published after deleting closed web part")
}
#Approve if required
if ($Page.ParentList.EnableModeration) { $Page.Approve("Approved") }
}
}
}
So the rule of Thumb is: If you don’t need a web part in a page, delete it! You can export the web part and use it later, if you want.
I agree with the rest above – good script!
You’re my hero Salaudeen!! I don’t know how the heck you even found that “?contents=1” parameter, or why in the world SharePoint doesn’t have a link to it in the GUI, but kudos!! You saved me the trouble of recreating a couple pages from scratch. 🙂
Me too. Gift that keeps on giving years later!
I partially agree with Punk Rock Chef. You do have to check it out. Here’s a way..
if ($file.RequiresCheckout -eq $TRUE) { $webpartmanager.Web.GetFile($file.UniqueID).CheckOut()}
$webpartmanager.DeleteWebPart($webpart)
if ($file.RequiresCheckout -eq $TRUE) { $webpartmanager.Web.GetFile($file.UniqueID).CheckIn(“Deleted web part: ” + $webpart.Title)}
write-host $webpart.Title “deleted from” $web.URL
But, you don’t need the webpart ID to delete, you can use the Webpart object.
Hi Jakistra, Thanks – The Script is updated now!
I realize this post is old as the hills but think I should point out a couple things that gave me hours of trouble.
1. You’re probably going to have to check out the page the web part is on first
2. DeleteWebPart() takes the ID of the web part, not the object itself. This was throwing “..web part not on this page.” errors for days for me. It should look something like this: $webPartManager.DeleteWebPart(WebParts.[$webPart.ID])