Unknown's avatar

Posts by Simon Doy

I am an avid SharePoint enthusiast who works as an Independent SharePoint Consultant based in Leeds, United Kingdom. I am one of the organisers of the Yorkshire SharePoint User Group in the United Kingdom. I have been designing and building SharePoint solutions since 2006.

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!

Content Subscriber Timer Job Error “A content type failed to be syndicated: System.Xml.Schema.XmlSchemaValidationException”


Introduction

We are using SharePoint’s Managed Metadata Service Application’s Content Type Hub model to manage the Content Types and Site Columns.

I’d highly recommend the following Technet Article for more information, Plan to share terminology and content types

Anyway, the approach to adding new metadata to the Content Types is using Feature Upgrading which has been interesting and has caused a few problems, which I have blogged about in the past.

Whilst researching the different options for the upgrade process I stumbled over a problem when using PowerShell to add a field to the Site Collection. This problem really only appears when you are using the Field within a Content Type that is being published to other site collections as part of a Content Type Hub.

The PowerShell worked and the Site Column was successfully created using the method. SPFieldCollection.AddFieldAsXml() function. However, when it came to pushing the changes out to the other site collections using the Managed Metadata’s Content Type Subscriber timer job the following errors were logged to the SharePoint ULS Log:-

  • “The element ‘FieldTemplate’ in namespace ‘urn:deployment-manifest-schema’ has invalid child element ‘Field’ in namespace ‘http://schemas.microsoft.com/sharepoint/’. List of possible elements expected: ‘Field’ in namespace ‘urn:deployment-manifest-schema’.”
  • “Received an error message from import: The element ‘FieldTemplate’ in namespace ‘urn:deployment-manifest-schema’ has invalid child element ‘Field’ in namespace ‘http://schemas.microsoft.com/sharepoint/’. List of possible elements expected: ‘Field’ in namespace ‘urn:deployment-manifest-schema’.. The recommendation is:”
  • “A content type failed to be syndicated: System.Xml.Schema.XmlSchemaValidationException: The element ‘FieldTemplate’ in namespace ‘urn:deployment-manifest-schema’ has invalid child element ‘Field’ in namespace ‘http://schemas.microsoft.com/sharepoint/’. List of possible elements expected: ‘Field’ in namespace ‘urn:deployment-manifest-schema’.    “

Investigation

The investigation started by looking at the process of adding the field to SharePoint.

The process being used is as follows:-

  • Load a SharePoint Elements file which has fields defined in it.
  • An example of the element.xml file is shown below
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Field ID="{38384FAD-5BF2-42D6-9243-5BE95F17E5FD}" Type="Text" Name="ITSPFieldName" StaticName="ITSPFieldName" DisplayName="iThink SharePoint Field" Description="Field does something" Group="iThink SharePoint Site Columns" />

</Elements>

 
  • Load the file into PowerShell using the Get-Content Cmdlet
  • Get a reference to the Content Type Hub using Get-SPSite
  • Get the <Field /> element
  • Add a field using the <Field />element and the Site Collection’s Root Web Fields property and AddFieldAsXml() function

Here is a snippet of the PowerShell script that was being executed to do the above:-

$contenttypehub = Get-SPSite -Identity http://sharepoint/hub;
[xml]$elementFile = Get-Content .\myelement.xml;
$fieldXml = $elementFile.Elements.Field[0];
$addedFieldName = $contenttypehub.RootWeb.Fields.AddFieldAsXml($fieldXml.OuterXml);
if($addedFieldName -ne $null)
{
Write-Host "Added Field with InternalFieldName: " $addedFieldName;
}
else {
Write-Warning "Failed to Add Field with Xml: " $fieldXml.OuterXml;
}

Once the script has run then the field is created and is available for assigning to the Content Type. The field is added to the Content Type successfully. However as mentioned previously when the Content Type Subscriber Hub Timer job is run then the errors are displayed about the Field’s SchemaXml .

So what’s going wrong?

Well after examining the Field’s SchemaXml property, I could see the issue.

The field’s schema was displayed using the following script:-

$fieldName = "FOSScannedDocumentId";
$contenttypehub = Get-SPSite -Identity http://sharepoint/hub;
$checkField = $contenttypehub.RootWeb.Fields | ?{$_.InternalName -like $fieldName};
$checkField.SchemaXml;

The output of the command showed the Field’s Schema Xml had an added Element as shown below:-


<Field ID="{38384FAD-5BF2-42D6-9243-5BE95F17E5FD}" Type="Text" Name="ITSPFieldName" StaticName="ITSPFieldName" DisplayName="iThink SharePoint Field" Description="Field does something" Group="iThink SharePoint Site Columns"  xmlns="
http://schemas.microsoft.com/sharepoint/" />

So what was happening, well PowerShell is being well behaved and adding the namespace attribute from the parent <Elements> node to this child node. Unfortunately SharePoint is not expecting this additional attribute as part of the Field’s SchemaXml and it causes the validation of the Xml to fail. Hence the XmlSchemaValidationException.

Solution

The solution was to modify the string being passed into the AddFieldFromXml() function.

This was achieved by modifying the script to remove the xmlns attribute :-


$removeNamespaceString = 'xmlns="http://schemas.microsoft.com/sharepoint/"';
[xml]$elementFile = Get-Content .\myelement.xml;
$fieldXml = $elementFile.Elements.Field[0];
$fieldXmlString = $fieldXml.OuterXml.Replace($removeNamespaceString, "");
$addedFieldName = $contenttypehub.RootWeb.Fields.AddFieldAsXml($fieldXmlString);

This script will find the string with attribute name of xmlns and replace it with a blank string.

Now, when the Field is added using this fixed version of the <Field/> element the Content Type Subscription timer job completes successfully!