Feature Upgrade Issue: Deleted SPWebs : An error occurred while enumerating through a collection


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

The following PowerShell was run to query for Features that need to be upgraded.

 $site=Get-SPSite http://sharepoint; $site.QueryFeatures("Web", $true); 

The result of the script displayed the following:-

 $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.

 $site = Get-SPSite http://sharepoint; $site.RecycleBin | ?{$_.ItemType -eq "Web"}; 

The script will display the SharePoint Web Objects that have been deleted and are still found in the site collections recycle bin.

The deleted SPWeb objects can be removed from the recycle bin using the following PowerShell command.

 $site = Get-SPSite http://sharepoint;  $deletedWebs = $site.RecycleBin | ?{$_.ItemType -eq "Web"}; $deletedWebs | % {$site.RecycleBin.Delete($_.Id)} 

This will delete the SPWeb objects from the recycle bin and the Feature Upgrade process can continue.

Please be careful when running this script! Only run it when you know that none of the SharePoint Web sites are not needed!

 

Anyway hope that helps!

Useful Visual Studio External Tools


Introduction

I have been meaning to document this for a while. Every time I set up a new machine I have to check the configuration of my Visual Studio external tools.

External Tools? If you don’t know what I am talking about then take a look at the image below.

image

Currently I have the following External Tools:-

  • Create GUID – this allows me to quickly get a new GUID when creating all those SharePoint resources, including Content Types, List Schemas, Feature Receivers etc.
  • Get Public Key Token – this uses the .Net Framework Signing Tool (sn.exe) to get the Public Key token, although with the new SharePoint tools in Visual Studio this isn’t needed so much there are always those odd occasions.
  • Get Full Assembly Name – This is used lots particularly when having to hack together various SharePoint Xml files or Entity Framework resource connection strings. I can’t take credit for this one, Sahil Malek – http://blah.winsmarts.com/2009-12-SharePoint_Productivity_Tip_of_the_day.aspx), did all the hard work.
  • Get IIS Web Application Information – This saves me so much time when debugging code especially, feature receivers, application page, web part code. The tool will display a list of all the Web Applications and there Process ID (PID).

Setting up the Tools

Create GUID Tool

First of all locate the Guidgen Tool which should be found in your Windows SDK folder. The path will depend on the Windows Version you are running, this one is for Windows 2008 R2. “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\”

  • The GUID Generator application can be found in the bin subfolder
  • Full Path: “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\guidgen.exe”
  • Now you have the path, fire up Visual Studio

clip_image002

  • Click Tools->External Tools
  • Click Add
  • Title: Generate GUID
  • Command: : “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\guidgen.exe”
  • Click Apply

clip_image004

When this tool is used then the following window will popup:-

clip_image006

Get Public Key Token Tool

This retrieves the public key token for the assembly that is associated to the file that is open in Visual Studio.

To setup the tool do the following:-

  • Get the Path to the SN.exe tool which is found in the .Microsoft SDK Path
  • “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\sn.exe”
  • From Visual Studio
  • Click Tools->External Tools
  • Click Add
  • Title: Get Public Key Token
  • Command: : “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\sn.exe”
  • Attributes: -Tp $(TargetPath)
  • Check “Use Output Window”
  • Click Apply

clip_image008

When the External Tool is used then the following output will appear in Visual Studio’s Output Window

clip_image010

Get Full Assembly Name Tool

This tool is excellent and saves me lots of time when you need the full Assembly Name for all the numerous SharePoint development tasks.

The setup of the tool comes from Sahil Malek (http://blah.winsmarts.com/2009-12-SharePoint_Productivity_Tip_of_the_day.aspx).

  • Fire up Visual Studio
  • Click Tools->External Tools
  • Click Add
  • Title: Get Full Assembly Path
  • Command: PowerShell
  • Arguments: -command “[System.Reflection.AssemblyName]::GetAssemblyName(\”$(TargetPath)\”).FullName”
  • Check “Use Output Window”
  • Click Apply

clip_image012

The output for this tool is as follows:-

clip_image014

Get IIS Web Application Info

This tool is great for getting information on the Web Server Application Pools. This is great if you need to debug a particular Web Application Pool Process.

  • Fire up Visual Studio
  • Click Tools->External Tools
  • Click Add
  • Title: Get IIS WP Info
  • Command: “c:\windows\system32\inetsrv\appcmd.exe”
  • Arguments: list WP
  • Check “Use Output Window”
  • Click Apply

clip_image016

The Output for this tool is as follows:-

clip_image018

Conclusion

I hope you find some of those tools useful, I would love to hear about any that you use.