Introduction
Recently I published a post about issues when upgrading Site Scope features in SharePoint. The issue was related to deleted Site Collections which were still in the recycle bin.After resolving this issue I decided to do some testing with other deleted SharePoint objects. The next logical object type to delete was an SPWeb object.
Unfortunately further issues were found and the following section explains how they were found and the approach to resolve them.
How the Issue was Approached
The approach taken was the following:-- Build a Web Scoped Feature marked v1.0.0.0
- Install the SharePoint Solution
- Create a number of Webs and Activate the feature on those webs
- Delete one of the Webs
- Update the Web Scoped Feature to v2.0.0.0
- Upgrade the SharePoint Solution to deploy the new version of the Web Scoped Feature
- Use Install-SPFeature [FeatureName] –Force to upgrade the feature
- Run a PowerShell command to execute the SPSite.QueryFeatures() function
1
| $site .QueryFeatures( "Web" , $true ); An error occurred while enumerating
through a collection: Unable to access web scoped feature (Id:
f41cc668-37e5-4743-b4a8-74d1db3fd8a4) because it references a
non-existent or broken web (Id: 3bd828cf-b747-4111-b888-5953b0d9aaa3) on
sit e 'http://dev.itsp.local' .
Exception: System.ArgumentException: Value does not fall within the
expected range. at Microsoft.SharePoint.SPWebCollection.get_Item(Guid
id) at
Microsoft.SharePoint.SPFeatureEnumeratorBase.GetCachedWeb(SPSite site,
Gu id webId, Guid featureId). At line:1 char:20 + $site .QueryFeatures >> ( "Web" , $true )
+ CategoryInfo : InvalidOperation:
(Microsoft.Share...esultCollec tion:SPFeatureQueryResultCollection)
[], RuntimeException + FullyQualifiedErrorId : BadEnumeration |
Solution
The approach to solving this issue was not to write a workaround but to run a script which checks for deleted SPWeb objects in the site collection.
1
|
The deleted SPWeb objects can be removed from the recycle bin using the following PowerShell command.
1
| $site = Get-SPSite http://sharepoint; $deletedWebs = $site .RecycleBin | ?{ $_ .ItemType -eq "Web" }; $deletedWebs | % { $site .RecycleBin.Delete( $_ .Id)} |
Please be careful when running this script! Only run it when you know that none of the SharePoint Web sites are not needed!