Welcome to MSDN Blogs Sign in | Join | Help

While running content deployment import job on destination farm, you get the following warning message and the import job completes successfully.


This message would appear when trying to import a View or a Form template document.

=============================================

Progress: Importing File Documents/Forms/template.doc.
Warning: User or group 5 cannot be resolved.

=============================================

This warning message can be ignored. What this really means is that the 'Modified By' property of the imported item (usually a View or Form on which the error was thrown) is changed to the account of the user importing the content.

This means that if a specific template document say ‘/Forms/template.doc’ is modified by a user 'User A' in the source and exported, then while importing in destination farm, the running import job will set the ‘Modified By’ property of the imported item with the account of the user that is running the import job on the destination farm. Note though that the documents created using this template are not affected.

While running content deployment import job on destination farm, you get the following error message and the import job fails.
This message would appear when trying to import a User.

====================================================================================

Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.

[10/15/2009 1:01:22 AM]: Progress: Importing User Domain\UserName.
[10/15/2009 1:01:23 AM]: FatalError: Save Conflict
Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.

   at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish)
   at Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents)
   at Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents)
   at Microsoft.SharePoint.SPListItem.MigrationAddOrUpdate(Boolean bAddNew, Boolean bIsPublish, Guid newGuidOnAdd, Boolean bNoVersion, Boolean suppressAfterEvents)
   at Microsoft.SharePoint.Deployment.ListItemSerializer.SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
   at Microsoft.SharePoint.Deployment.XmlFormatter.ParseObject(Type objectType, Boolean isChildObject)
   at Microsoft.SharePoint.Deployment.XmlFormatter.DeserializeObject(Type objectType, Boolean isChildObject, DeploymentObject envelope)
   at Microsoft.SharePoint.Deployment.XmlFormatter.Deserialize(Stream serializationStream)
   at Microsoft.SharePoint.Deployment.ObjectSerializer.Deserialize(Stream serializationStream)
   at Microsoft.SharePoint.Deployment.ImportObjectManager.ProcessObject(XmlReader xmlReader)
   at Microsoft.SharePoint.Deployment.SPImport.DeserializeObjects()
   at Microsoft.SharePoint.Deployment.SPImport.Run()

[10/15/2009 1:01:26 AM]: Progress: Import Completed.
[10/15/2009 1:01:26 AM]: Finish Time: 10/15/2009 1:01:26 AM.
[10/15/2009 1:01:26 AM]: Completed with 0 warnings.
[10/15/2009 1:01:26 AM]: Completed with 1 errors.

====================================================================================

This is an expected error message if a user was created on the source farm and then post a deployment, the user was removed from the ‘All Users’ list on the source. Now when we try to import the user deletion activity to the destination farm, we get this error message.

Installing the June 09 CU ensures that the error message changes to non-Fatal and the content deployment import job succeeds.

You might face a peculiar problem when you implement the custom dictionary functionality in SharePoint. This functionality is documented under "Plan dictionary customizations" section of article http://technet.microsoft.com/en-us/library/cc263367.aspx

All the words in the file uploaded the first time are recognized by the Spell checker. But if you make any modifications to the ‘custom dictionary.txt’ file and upload it again, the spell checker might not pick it up.

To workaround this issue, you may clear the system temp location - %systemroot%\temp location and try the spell checker again. You may also search for this custom dictionary file saved in the temp location and delete that single file (name is in the format GUID.txt)

Recently I researched on case where the SharePoint Service Pack 2 upgrade failed with the following exception.

[SPIisWebSiteWssSequence] [ERROR] [7/18/2009 11:13:56 PM]: Action 3.1.3.0 of Microsoft.SharePoint.Upgrade.SPIisWebSiteWssSequence failed.
[SPIisWebSiteWssSequence] [ERROR] [7/18/2009 11:13:56 PM]: The system cannot find the path specified.
[SPIisWebSiteWssSequence] [ERROR] [7/18/2009 11:13:56 PM]:    at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.PropertyValueCollection.PopulateList()
   at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
   at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
   at Microsoft.SharePoint.Administration.SPIisApplicationPool.get_PeriodicRestartMemory()
   at Microsoft.SharePoint.Administration.SPProvisioningAssistant.EnableMemoryBasedAppPoolRecycling(SPIisApplicationPool local)
   at Microsoft.SharePoint.Administration.SPProvisioningAssistant.EnableMemoryBasedAppPoolRecycling(String applicationPoolId)
   at Microsoft.SharePoint.Upgrade.EnableMemoryBasedAppPoolRecycling.Upgrade()
   at Microsoft.SharePoint.Upgrade.SPActionSequence.Upgrade()

Looking at the call stack it was clear that SharePoint was trying to query the “PeriodicRestartMemory” setting of an application pool and that action failed with “The system cannot find the path specified”.

So the first step we did was check if any of the Application Pools used by SharePoint Web Applications were deleted in the recent past and for sure we got confirmation that there were some changes made. Few application pools were deleted manually through IIS Manager. The related Web Applications were then associated with a different Application Pool through IIS.

Now of course doing this does not change the association in SharePoint configuration. SharePoint does not provide a UI option to modify the Application Pool attached to a Web Application, you can use Object Model code to do it though.

So the solution here is to either recreate those Application Pools that were missing OR to update SharePoint configuration with the new association as per IIS setting.

Here is how you can do it.

Option 1:

Delete and recreate the web application using SharePoint. This will surely clear the orphan application pool entry.

Option 2:

1. Stop the “Windows SharePoint Services Web Application” service on the WFE. This step will remove all the application pools and web applications on that WFE.

2. Now restart the ‘Windows SharePoint Services Web Application’ service. This step will now recreate all the Web Applications and Applications Pools (including the missing ones) in IIS.

Please ensure you have a backup of the IIS metabase and the virtual directory folders as any customization here may be lost.

Options 3:

Finally we can use the object model to update the Application Pool association for every Web Application that points to a specific ‘deleted’ application pool. In an attempt to achieve this requirement, I wrote the below powershell script.

##############################################################################
## This script searches for all Web Applications using a specific application pool 'Old Application Pool' and updates it's property in SharePoint configuration to use a 'New Application Pool'
## USAGE:
## REQUIREMENT: Ensure the new application pool to be used is already registered in SharePoint. This happens when you create a new Web Application with a new Application pool.
## SYNTAX:      ChangeApplicationPool <old application pool name> <new application pool name>"
## NOTE:        Application pool name is case sensitive.
##############################################################################

# Define 2 parameters for this script
param([string] $oldAPName, [string] $newAPName)

# Check if both params are passed, else show Syntax.
if ($newAPName -eq "")
{
   "Syntax: ChangeApplicationPool <old application pool name> <new application pool name>"
   exit;
}

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")

$WebService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

## Get reference for the new application pool within the list of SharePoint objects
[Microsoft.SharePoint.Administration.SPApplicationPoolCollection] $appPools = $webService.ApplicationPools;
$newAppPool = $NULL;
foreach ($appPool in $appPools)
{
    if ($appPool.Name -eq $newAPName)
    {
        [Microsoft.SharePoint.Administration.SPApplicationPool]$newAppPool = $appPool;
    }
}

## If new application pool is not found, then give error and exit
if($newAppPool -eq $NULL)
{
    "ERROR: The New application pool to be assigned was not found within SharePoint!"
    "REQUIREMENT: Ensure the new application pool to be used is already registered in SharePoint. This happens when you create a new Web Application with a new Application pool."
    exit;
}

## Now loop through all Web Applications to find a match of the old Application pool and update it with New App pool.
[Microsoft.SharePoint.Administration.SPWebApplicationCollection] $webApps = $webService.WebApplications

"Searching through all Web Applications for Old Application pool - " + $oldAPName + " and changing it to - " + $newAPName
$count=0;
foreach ($webApp in $webApps)
{
    $webApp.DisplayName + " uses application pool " + $webApp.ApplicationPool.Name
    if($webApp.ApplicationPool.Name -eq $oldAPName)
    {
        $webApp.ApplicationPool = $newAppPool;   ## Changed to new Application pool reference.
        $webApp.Update();
        "............" + $webApp.DisplayName + " now uses the new application pool " + $webApp.ApplicationPool.Name
        $count = $count + 1;
    }
}
"Found and replaced " + $count + " web application(s)"

if($count -eq 0)
{
   "Syntax: ChangeApplicationPool <old application pool name> <new application pool name>"
   "Ensure the application pool name is an exact match"
}

########################################################################################################################

Disclaimer: The above code is provided "As Is". This is just a sample code and is not production ready.

I had few thousand user profiles in my SSP and needed to delete them. So here is a script that I wrote to list all the user profiles in an SSP. If you need to remove the user profiles, then just use the UserProfileManager.RemoveUserProfile method and pass it the UserProfile.Id property.

###################################################################################################

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")

###########################
# "PUT THE SSP NAME HERE"
$SSPName = "SharedServices1"
###########################
$ServerContext = [Microsoft.Office.Server.ServerContext]::GetContext($SSPName)
$UPManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServerContext);
$enumProfiles = $UPManager.GetEnumerator();
"Total User Profiles available:" + $UPManager.Count
$count=0;
foreach ($oUser in $enumProfiles)
{
    $count = $count + 1;
    "(" + $count + ") " + $oUser.Item("PreferredName");
}

###################################################################################################

Disclaimer: The above code is provided "As Is". This is just a sample code and is not production ready.

Another script I wrote is to delete all items from a List.

###################################################################################################

[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

# "Enter the site URL here"
$SITEURL = "http://serverurl"

$site = new-object Microsoft.SharePoint.SPSite ( $SITEURL )
$web = $site.OpenWeb()
"Web is : " + $web.Title

# Enter name of the List below
$oList = $web.Lists["ENTER LIST NAME HERE"];

"List is :" + $oList.Title + " with item count " + $oList.ItemCount

$collListItems = $oList.Items;
$count = $collListItems.Count - 1

for($intIndex = $count; $intIndex -gt -1; $intIndex--)
{
        "Deleting : " + $intIndex
        $collListItems.Delete($intIndex);
}

###################################################################################################

Disclaimer: The above code is provided "As Is". This is just a sample code and is not production ready.

I have been experimenting with PowerShell scripting for the past few months.

Below is a script I have written to remove all users in a specific SharePoint group. There have been many instances where we find users have added too many individual user accounts to a specific SharePoint group. This causes many issues like search failing, performance issues, etc.

################################################################################################################

[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
[System.Reflection.Assembly]::Load("System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

###########################
# "Enter the site URL here"
$SITEURL = "http://serverurl"

# "Name of Site group from which users have to be removed"
$SITEGROUP = "Site_Contributors"

###########################

$site = new-object Microsoft.SharePoint.SPSite ( $SITEURL )
$web = $site.OpenWeb()
"Web is : " + $web.Title

$oSiteGroup = $web.SiteGroups[$SITEGROUP];

"Site Group is :" + $oSiteGroup.Name
$oUsers = $oSiteGroup.Users

foreach ($oUser in $oUsers)
{
    "Removing user : " + $oUser.Name
    $oSiteGroup.RemoveUser($oUser)
}

################################################################################################################

Disclaimer: The above code is provided "As Is". This is just a sample code and is not production ready.

We had an interesting case the other day. The customer had a variation enabled SharePoint site with multiple sites for different languages. He would export one of the language based site and sends it to the company that handles the translation. Once the export file (.cmp) was converted and returned, he used to import it back into the variation site for that specific language. This used to work for all languages, but failed for one specific site.

The import would fail with the following error: (You will see this error if debug & callstack are set to true in the web.config).

<error><message>An error occurred while parsing EntityName. Line 4, position 38.</message><full>System.Xml.XmlException: An error occurred while parsing EntityName. Line 4, position 38. at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.Throw(String res, Int32 lineNo, Int32 linePos) at System.Xml.XmlTextReaderImpl.HandleEntityReference(Boolean isInAttributeValue, EntityExpandType expandType, Int32&amp; charRefEndPos) at System.Xml.XmlTextReaderImpl.ParseText(Int32&amp; startPos, Int32&amp; endPos, Int32&amp; outOrChars) at System.Xml.XmlTextReaderImpl.FinishPartialValue() at System.Xml.XmlTextReaderImpl.get_Value() at System.Xml.XmlReader.ReadString() at System.Xml.XmlTextReaderImpl.ReadString() at Microsoft.SharePoint.Publishing.SummaryLink..ctor(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.SummaryLinkCollection.Deserialize(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue.deserializeSummaryLinks(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue.deserialize(String serializedValue) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue..ctor(String serializedValue) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkField.GetFieldValue(String value) at Microsoft.SharePoint.SPListItem.SetValue(String strName, Object value, SPField field, Boolean protectFields) at Microsoft.SharePoint.SPListItem.set_Item(Guid fieldId, Object value) at Microsoft.SharePoint.Deployment.ListItemSerializer.UpdateFieldData(SPListItem listItem, ImportObjectManager objectManager, Guid docId, String fieldName, String value, String value2, Guid gFieldId, Boolean&amp; bCreated, Dictionary`2 brokenFields) at Microsoft.SharePoint.Deployment.ListItemSerializer.UpdateFieldData(SPListItem listItem, Guid docId, Boolean&amp; bCreated, SPContentTypeId contentTypeId, ImportObjectManager objectManager, Object data) at Microsoft.SharePoint.Deployment.ListItemSerializer.SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) at Microsoft.SharePoint.Deployment.XmlFormatter.ParseObject(Type objectType, Boolean isChildObject) at Microsoft.SharePoint.Deployment.XmlFormatter.DeserializeObject(Type objectType, Boolean isChildObject, DeploymentObject envelope) at Microsoft.SharePoint.Deployment.XmlFormatter.Deserialize(Stream serializationStream) at Microsoft.SharePoint.Deployment.ObjectSerializer.Deserialize(Stream serializationStream) at Microsoft.SharePoint.Deployment.ImportObjectManager.ProcessObject(XmlReader xmlReader) at Microsoft.SharePoint.Deployment.SPImport.DeserializeObjects() at Microsoft.SharePoint.Deployment.SPImport.Run() at Microsoft.SharePoint.Publishing.Internal.DeploymentWrapper.ImportObjects(String fileName) at Microsoft.SharePoint.Publishing.Internal.WebControls.ImportVariation.DoWork() at Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob.&lt;ThreadEntryPoint&gt;b__11() at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)</full><customData></customData></error><error><message>An error occurred while parsing EntityName. Line 4, position 38.</message><full>System.Xml.XmlException: An error occurred while parsing EntityName. Line 4, position 38. at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.Throw(String res, Int32 lineNo, Int32 linePos) at System.Xml.XmlTextReaderImpl.HandleEntityReference(Boolean isInAttributeValue, EntityExpandType expandType, Int32&amp; charRefEndPos) at System.Xml.XmlTextReaderImpl.ParseText(Int32&amp; startPos, Int32&amp; endPos, Int32&amp; outOrChars) at System.Xml.XmlTextReaderImpl.FinishPartialValue() at System.Xml.XmlTextReaderImpl.get_Value() at System.Xml.XmlReader.ReadString() at System.Xml.XmlTextReaderImpl.ReadString() at Microsoft.SharePoint.Publishing.SummaryLink..ctor(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.SummaryLinkCollection.Deserialize(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue.deserializeSummaryLinks(XmlReader reader, Int32 deserializedSchemaVersion) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue.deserialize(String serializedValue) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkFieldValue..ctor(String serializedValue) at Microsoft.SharePoint.Publishing.Fields.SummaryLinkField.GetFieldValue(String value) at Microsoft.SharePoint.SPListItem.SetValue(String strName, Object value, SPField field, Boolean protectFields) at Microsoft.SharePoint.SPListItem.set_Item(Guid fieldId, Object value) at Microsoft.SharePoint.Deployment.ListItemSerializer.UpdateFieldData(SPListItem listItem, ImportObjectManager objectManager, Guid docId, String fieldName, String value, String value2, Guid gFieldId, Boolean&amp; bCreated, Dictionary`2 brokenFields) at Microsoft.SharePoint.Deployment.ListItemSerializer.UpdateFieldData(SPListItem listItem, Guid docId, Boolean&amp; bCreated, SPContentTypeId contentTypeId, ImportObjectManager objectManager, Object data) at Microsoft.SharePoint.Deployment.ListItemSerializer.SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) at Microsoft.SharePoint.Deployment.XmlFormatter.ParseObject(Type objectType, Boolean isChildObject) at Microsoft.SharePoint.Deployment.XmlFormatter.DeserializeObject(Type objectType, Boolean isChildObject, DeploymentObject envelope) at Microsoft.SharePoint.Deployment.XmlFormatter.Deserialize(Stream serializationStream) at Microsoft.SharePoint.Deployment.ObjectSerializer.Deserialize(Stream serializationStream) at Microsoft.SharePoint.Deployment.ImportObjectManager.ProcessObject(XmlReader xmlReader) at Microsoft.SharePoint.Deployment.SPImport.DeserializeObjects() at Microsoft.SharePoint.Deployment.SPImport.Run() at Microsoft.SharePoint.Publishing.Internal.DeploymentWrapper.ImportObjects(String fileName) at Microsoft.SharePoint.Publishing.Internal.WebControls.ImportVariation.DoWork() at Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob.&lt;ThreadEntryPoint&gt;b__11() at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock) at Microsoft.Office.Server.Diagnostics.ULS.SendWatsonOnExceptionTag(ULSTagID tagID, ULSCat categoryID, String output, Boolean fRethrowException, TryBlock tryBlock, CatchBlock catchBlock, FinallyBlock finallyBlock) at Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob.&lt;ThreadEntryPoint&gt;b__f() at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)</full><customData></customData></error>

The ULS Logs would throw an error - "An error occurred while parsing EntityName. Line 4, position 38." followed by the callstack.

 

So this surely looks like a malformed XML file. So we extracted the Manifest.XML file and opened it up in Internet Explorer, expecting it to fail with a similar error - no luck here! After some research and some code to parse the XML file, we got closer to the problem. This was happening because the manifest.xml file had tags that have values which were treated as STRINGs and they internally were again encoded XML strings. So when the import job runs, it extracts the value from the parent XML and then decodes the value to form a new XML string which is again parsed. This is where the failure used to happen. We had a huge Manifest.xml file, so to speed up the process,

So we attached a debugger to the import job and when the exception happened, dumped the stack and found the string that caused the issue.

The exported version of the manifest.xml had the following XML string :

<Field Name="SummaryLinks2" Value="&lt;div title=&quot;_schemaversion&quot; id=&quot;_3&quot;&gt;&#xD;&#xA; &lt;div title=&quot;_links&quot;&gt;&#xD;&#xA; &lt;div title=&quot;_link&quot;&gt;&#xD;&#xA; &lt;span title=&quot;_title&quot;&gt;Hot &amp;amp; Cold&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_order&quot;&gt;1&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_begincolumn&quot;&gt;True&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_description&quot;&gt;Description&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_linkurl&quot;&gt;&#xD;&#xA; &lt;a href=&quot;/English/Documents/Forms/AllItems.aspx&quot;&gt;/English/Documents/Forms/AllItems.aspx&lt;/a&gt;&#xD;&#xA; &lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_style&quot;&gt;Default&lt;/span&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA; &lt;div title=&quot;_view&quot;&gt;&#xD;&#xA; &lt;span title=&quot;_columns&quot;&gt;1&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_linkstyle&quot;&gt;&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_groupstyle&quot;&gt;&lt;/span&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA;&lt;/div&gt;" FieldId="27761311-936a-40ba-80cd-ca5e7a540a36" />

</Fields>

The imported version had the following XML:

<Field Name="SummaryLinks2" Value="&lt;div title=&quot;_schemaversion&quot; id=&quot;_3&quot;&gt;&#xD;&#xA; &lt;div title=&quot;_links&quot;&gt;&#xD;&#xA; &lt;div title=&quot;_link&quot;&gt;&#xD;&#xA; &lt;span title=&quot;_title&quot;&gt;Hot &amp; Cold&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_order&quot;&gt;1&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_begincolumn&quot;&gt;True&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_description&quot;&gt;Description&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_linkurl&quot;&gt;&#xD;&#xA; &lt;a href=&quot;/English/Documents/Forms/AllItems.aspx&quot;&gt;/English/Documents/Forms/AllItems.aspx&lt;/a&gt;&#xD;&#xA; &lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_style&quot;&gt;Default&lt;/span&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA; &lt;div title=&quot;_view&quot;&gt;&#xD;&#xA; &lt;span title=&quot;_columns&quot;&gt;1&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_linkstyle&quot;&gt;&lt;/span&gt;&#xD;&#xA; &lt;span title=&quot;_groupstyle&quot;&gt;&lt;/span&gt;&#xD;&#xA; &lt;/div&gt;&#xD;&#xA;&lt;/div&gt;" FieldId="27761311-936a-40ba-80cd-ca5e7a540a36" />

</Fields>

So what really happens is if you have a Summary Links Web Part on the variation page and it has text like "Hot&Cold", then this would be encoded the first time as Hot&amp;Cold. Now when this is packaged in the Manifest.xml - this is again encoded to form Hot&amp;amp;Cold and this structure needs to be mainted. The XML encoded values should not be changed. You will find more information on this at http://support.microsoft.com/kb/251354

When you do a people search on SharePoint, you see the results in the "Results by Social Distance" view. The other view to choose is "View by Relevance".

 

image

 

In case you find that the output shows the results by default in "Results by Relevance" and the link for "View by Social Distance" is missing, then you probably are missing few permissions.

To fix this try the following steps,

  1. Browse to the SSP.
  2. Select "Personalization services permissions".
  3. Here the "NT AUTHORITY\Authenticated Users" user needs to have "Personal Features, Personal Site" rights by default.
  4. If this account is missing, then click on "Add Users/Groups".
  5. Enter "NT AUTHORITY\Authenticated Users" for User and select "Create personal site" and "Use personal features" check box.
  6. Click on Save.

This should bring back the "Results by Social Distance" under people search.

If you apply the Obsidian Theme to your MySite, the Colleague tracker webpart might show some blank rows! It will look something like this,

 

image

 

On investigating further by selecting that area using the mouse, you find that the text is actually there. This happens because the background color and the text color are the same and hence we do not see the Text.

 

image

 

How do we fix this?

You need to modify the Obsidian style sheet file to fix this.

table.ms-qrblinks tr td a, table.ms-qrblinks tr td a:link, table.ms-qrblinks tr td a:visited, table.ms-qrblinks tr td a:hover {
color:#ffffff;
}

  • Change this to

table.ms-qrblinks tr td a, table.ms-qrblinks tr td a:link, table.ms-qrblinks tr td a:visited, table.ms-qrblinks tr td a:hover {
color:#ffffff;
color:#ff0000;
}

  • The reason we are adding the 2nd color attribute is to overwrite the earlier color attribute value. We can also replace the first value if needed.
  • This sets the foreground color to RED. You can of course set this to a color of your choice.
  • Save the file and browse to the MySite again and you should be able to see the data.

 

image

What this blog describes is the steps you need to get SharePoint to crawl a Forms based Authentication site. What are the issues you may face and how to resolve them.

Requirements:

  • Microsoft Office SharePoint Server 2007
  • A forms based authentication enabled site (NOTE: This could be a SharePoint based FBA site too)

We start by downloading addrule.exe to the SharePoint server. This tool is available at SharePoint Server 2007 Tool: Add/Edit Crawl Rules with Form/Cookie Credentials.

We then create a XML file to feed the addrule.exe. The specification of the XML file is documented in Searching Sites Protected by Forms Authentication with Enterprise Search in SharePoint Server 2007 and even in SharePoint Server 2007 Tool: Add/Edit Crawl Rules with Form/Cookie Credentials.

I get this Sample XML file created.

<rules ssp="SharedServices1">

<rule>
<path>http://fbasite/*</path>
<type>FORMS</type>
<auth_url>http://fbasite/_layouts/login.aspx?ReturnUrl=%2f</auth_url>
<login_type>POST</login_type>
<parameters>
<param name="UserName">administrator</param>
<param name="password">mypassword!</param>
<param name="login" public="true">Sign In</param>
<param name="__EVENTVALIDATION" public="true/wEWBQKLhuipCQLE96mtBQLLtsPBAgLkkP7MCgK/lZyyB9CK4YpD9xxOo46u87JbhTsQ5AkW</param>
</parameters>
<error_pages>
<error_page>/layouts/login.aspx</error_page>
</error_pages>
</rule>

</rules>

I then create a content source that points to the http://fbasite URL.

Then I run the command "addrule.exe myfba.xml" command to create a crawl rule in the SharePoint SSP search settings.

Many standard FBA sites will work using these steps. But some might still fail. I found 2 reasons why this can happen and they are,

  • We missed out few params that the FBA site expects.
  • The param value that we specified in the XML file is not URL encoded.

The solution is the same for both issues. We need to use this wonderful tool - Fiddler  that actually is a HTTP debugging proxy. This tool allows us to see the traffic between the client and server when using the HTTP protocol.

So the steps we take to fix this are,

  1. Install and start Fiddler.
  2. Browse to the http://fbasite site - the login page should show up.
  3. Enter the credentials to sign in.
  4. Ensure you were able to successfully login.
  5. Now switch to the Fiddler window and double click on the link in the Web Sessions window that points to the Login page.
  6. Then on the right hand page, select the "Session Inspector" tab and click on the "Raw" view.
  7. This is what you should see,

image

 

Here the section in RED is what is interesting. These are the parameters that are sent by the browser to log you in. This is exactly what is needed by SharePoint to login to the FBA site. If you look at the formatting of this text, it is something like this:

param1=value1&param2=value2&param3=value3

So if we copy each and every parameter in that string and its respective value to the addrule XML file, we should get SharePoint to login the way you logged in using the browser.

By copying all parameters we are resolving both the issue - that of missing params and also of the URL encoding.

NOTE: If the site is a SharePoint FBA site, then the recommendation is to extend and map the site to a NTLM site and then crawl the NTLM site. Prepare to crawl host-named sites that use forms authentication talks about this. But if you still would like to crawl the SharePoint site using the FBA credentials - then you need to make this adding configuration in the crawl rule.

  1. Browse to the Shared Services page -> Search Settings -> Crawl Rules
  2. Edit the crawl rule that was generated by the addrule.exe tool.
  3. Here select the check box for "Crawl SharePoint content as Http pages."

Now your SharePoint site will get crawled as a standard HTTP site using the FBA credentials, but note that you would miss a lot of SharePoint related functionality.

Note: If you are using Microsoft Search Server 2008, then you actually have UI that simplifies this process. There is an update planned to include the MSS features into MOSS. Once that's done, the UI should take care of finding the params to create the crawl rule.

Other reference articles:

  1. Searching Sites Protected by Forms Authentication with Enterprise Search in SharePoint Server 2007
  2. Prepare to crawl host-named sites that use forms authentication
  3. Sites that require forms-based authentication or cookie-based authentication are not crawled in SharePoint Server 2007
  4. Configure forms-based authentication (Office SharePoint Server)
 
Page view tracker