During a migration of a content database from a SharePoint 2010 to a brand new SharePoint 2013, everything seems to work fine except rendering of some GIF image were used in some pages.
Browsing the site with IE10 these images were not rendered. Using another browser these images were rendered correclty.
So I try to browse the "old" SharePoint 2010 with IE10 and images were rendered correctly.
SharePoint 2010 was served by Windows Server 2008R2 while SharePoint 2013 is served by Windows Server 2012 and IIS8.
The point is that when you create a new webapplication in SharePoint 2013 the IIS Virtual Server is created with two specific (local) HTTP Response Header.
One of this header (only IE9 and above versions is able to interprete this) is responsible of the behavior described:
X-Content-Type-Options: nosniff
Removing this custom header from every front-end webserver resolve the issues.
More info about this header can be read on MSDN at:
MIME-Handling Change: X-Content-Type-Options: nosniff
Thursday, February 28, 2013
Tuesday, February 19, 2013
SharePoint 2010 - Edit SharePoint Group raise Access Denied Exception
If you experience "Access Denied" exception editing SharePoint Group Property, probably this article can give you some suggestion.
SharePoint page that give you ability to edit group properties in SharePoint 2010 runs with the permissions of the user who invokes it.
The operations that were successful were those related to the Update of the characteristics of the group, and immediately after it was returned "Access Denied".
By reverse eng the assembly from which SharePoint editgrp.aspx inherits (Microsoft.SharePoint.ApplicationPages.dll), what is clear is that, following the method "sPGroup.Update ();" there's a call to a base method called "UpdateAdditionalProperties".
This method essentially updates the description of the group on the hidden list "UserInfo" (properties siteUserInfoList of the Site Collection) that keeps track of all information related to Users and Groups.
This method returns an Access Denied exception (from tracelog: SPRequest Unknown error occurred. More information: 0x80070005).
User is also redirected to AccessDenied.aspx page.
This is the code from SharePoint dll.
// Microsoft.SharePoint.ApplicationPages.EditGroup
protected override int DoOperation()
{
base.Trace.Write("Editing Group", "");
if (this.RadAllowRequestToJoinLeaveYes.Checked && !this.RadAutoAcceptRequestYes.Checked && !SPUtility.IsEmailServerSet(base.Web))
{
throw new SPException(SPResource.GetString("RequestJoinLeaveGroupEmailServerSettingsInvalid", new object[0]));
}
SPGroup sPGroup = base.Web.SiteGroups[this.hdnGrpName.Value];
if (sPGroup != null)
{
if (sPGroup.Name != this.m_strGrpName)
{
sPGroup.Name = this.m_strGrpName;
}
SPMember memberFromPeoplePicker = base.GetMemberFromPeoplePicker();
sPGroup.Owner = memberFromPeoplePicker;
sPGroup.AllowRequestToJoinLeave = this.RadAllowRequestToJoinLeaveYes.Checked;
sPGroup.AutoAcceptRequestToJoinLeave = this.RadAutoAcceptRequestYes.Checked;
sPGroup.OnlyAllowMembersViewMembership = this.RadViewMembershipGroupMembers.Checked;
sPGroup.AllowMembersEditMembership = this.RadEditMembershipGroupMembers.Checked;
if (this.RadAllowRequestToJoinLeaveYes.Checked && !this.RadAutoAcceptRequestYes.Checked)
{
sPGroup.RequestToJoinLeaveEmailSetting = this.TxtRequestEmail.Text.Trim();
}
sPGroup.ClearDistributionGroupErrorMessage();
if (base.DistributionGroupsAvailable)
{
ErrorPage.SetupInfoForMessageContainingLink(this.Context, "GroupDistributionGroupErrorMessageContainingLink", "GroupSettingsPage", base.Web.GetServerRelativeUrlFromUrl("_layouts/editgrp.aspx?Group=" + SPHttpUtility.UrlKeyValueEncode(sPGroup.Name)));
if (this.CreateDLTrue.Checked)
{
if (string.IsNullOrEmpty(sPGroup.DistributionGroupAlias))
{
sPGroup.CreateDistributionGroup(this.DLAlias.Text);
}
else
{
if (this.DLAlias.Text != sPGroup.DistributionGroupAlias)
{
sPGroup.RenameDistributionGroup(this.DLAlias.Text);
}
}
if (this.ArchiveListExisting.Checked)
{
List<SPList> list = new List<SPList>();
foreach (ListItem listItem in this.ArchiveListExistingLists.Items)
{
if (listItem.Selected)
{
list.Add(base.Web.Lists[new Guid(listItem.Value)]);
}
}
sPGroup.SetDistributionGroupArchives(new ReadOnlyCollection<SPList>(list), base.Web);
}
else
{
if (this.ArchiveListNew.Checked)
{
base.CreateNewArchiveList(sPGroup, base.Web, this.ArchiveListNewName.Text);
}
else
{
sPGroup.SetDistributionGroupArchives(new ReadOnlyCollection<SPList>(new List<SPList>()), base.Web);
}
}
}
else
{
if (this.CreateDLFalse.Checked && !string.IsNullOrEmpty(sPGroup.DistributionGroupAlias))
{
sPGroup.DeleteDistributionGroup();
}
}
ErrorPage.CleanupInfoForMessageContainingLink(this.Context);
}
sPGroup.Update();
}
base.UpdateAdditionalProperties(sPGroup.ID);
return 0;
}
*** This one is the method that raise "Access Denied" exception and the consequent UI redirect to the Access Denied Exception. ***
// Microsoft.SharePoint.ApplicationPages.CBaseNewGroup
protected void UpdateAdditionalProperties(int groupId)
{
SPList siteUserInfoList = base.Web.SiteUserInfoList;
SPListItem itemById = siteUserInfoList.GetItemById(groupId);
string text = this.txtGrpDescription.Text;
itemById["Notes"] = text;
int num = 1;
while (true)
{
string text2 = base.Request.QueryString["FieldName" + num.ToString(CultureInfo.InvariantCulture)];
if (string.IsNullOrEmpty(text2))
{
break;
}
string value = base.Request.QueryString["FieldValue" + num.ToString(CultureInfo.InvariantCulture)];
itemById[text2] = value;
num++;
}
itemById.Update();
}
At this point I've checked with powershell the property "EffectiveBasePermissions" over UserInfo list, comparing the result with another Test Farm (which is working fine).
On Test Farm this collection was valued at FullMask. On Production Farm this collection was listing a number of base permissions.
The missing permission is the one related to the Update User Information.
From central admin, at WebApplication level, invoking "User Permissions" dialog, what I've discovered is that there was no flag on the basic permission "Edit Personal User Information".
Settings this flag=true on the webapplication affected will result in no more "Access Denied" redirect .
This bug/behavior has been verified on SharePoint 2010 SP1 + October 2012 CU.
SharePoint page that give you ability to edit group properties in SharePoint 2010 runs with the permissions of the user who invokes it.
The operations that were successful were those related to the Update of the characteristics of the group, and immediately after it was returned "Access Denied".
By reverse eng the assembly from which SharePoint editgrp.aspx inherits (Microsoft.SharePoint.ApplicationPages.dll), what is clear is that, following the method "sPGroup.Update ();" there's a call to a base method called "UpdateAdditionalProperties".
This method essentially updates the description of the group on the hidden list "UserInfo" (properties siteUserInfoList of the Site Collection) that keeps track of all information related to Users and Groups.
This method returns an Access Denied exception (from tracelog: SPRequest Unknown error occurred. More information: 0x80070005).
User is also redirected to AccessDenied.aspx page.
This is the code from SharePoint dll.
// Microsoft.SharePoint.ApplicationPages.EditGroup
protected override int DoOperation()
{
base.Trace.Write("Editing Group", "");
if (this.RadAllowRequestToJoinLeaveYes.Checked && !this.RadAutoAcceptRequestYes.Checked && !SPUtility.IsEmailServerSet(base.Web))
{
throw new SPException(SPResource.GetString("RequestJoinLeaveGroupEmailServerSettingsInvalid", new object[0]));
}
SPGroup sPGroup = base.Web.SiteGroups[this.hdnGrpName.Value];
if (sPGroup != null)
{
if (sPGroup.Name != this.m_strGrpName)
{
sPGroup.Name = this.m_strGrpName;
}
SPMember memberFromPeoplePicker = base.GetMemberFromPeoplePicker();
sPGroup.Owner = memberFromPeoplePicker;
sPGroup.AllowRequestToJoinLeave = this.RadAllowRequestToJoinLeaveYes.Checked;
sPGroup.AutoAcceptRequestToJoinLeave = this.RadAutoAcceptRequestYes.Checked;
sPGroup.OnlyAllowMembersViewMembership = this.RadViewMembershipGroupMembers.Checked;
sPGroup.AllowMembersEditMembership = this.RadEditMembershipGroupMembers.Checked;
if (this.RadAllowRequestToJoinLeaveYes.Checked && !this.RadAutoAcceptRequestYes.Checked)
{
sPGroup.RequestToJoinLeaveEmailSetting = this.TxtRequestEmail.Text.Trim();
}
sPGroup.ClearDistributionGroupErrorMessage();
if (base.DistributionGroupsAvailable)
{
ErrorPage.SetupInfoForMessageContainingLink(this.Context, "GroupDistributionGroupErrorMessageContainingLink", "GroupSettingsPage", base.Web.GetServerRelativeUrlFromUrl("_layouts/editgrp.aspx?Group=" + SPHttpUtility.UrlKeyValueEncode(sPGroup.Name)));
if (this.CreateDLTrue.Checked)
{
if (string.IsNullOrEmpty(sPGroup.DistributionGroupAlias))
{
sPGroup.CreateDistributionGroup(this.DLAlias.Text);
}
else
{
if (this.DLAlias.Text != sPGroup.DistributionGroupAlias)
{
sPGroup.RenameDistributionGroup(this.DLAlias.Text);
}
}
if (this.ArchiveListExisting.Checked)
{
List<SPList> list = new List<SPList>();
foreach (ListItem listItem in this.ArchiveListExistingLists.Items)
{
if (listItem.Selected)
{
list.Add(base.Web.Lists[new Guid(listItem.Value)]);
}
}
sPGroup.SetDistributionGroupArchives(new ReadOnlyCollection<SPList>(list), base.Web);
}
else
{
if (this.ArchiveListNew.Checked)
{
base.CreateNewArchiveList(sPGroup, base.Web, this.ArchiveListNewName.Text);
}
else
{
sPGroup.SetDistributionGroupArchives(new ReadOnlyCollection<SPList>(new List<SPList>()), base.Web);
}
}
}
else
{
if (this.CreateDLFalse.Checked && !string.IsNullOrEmpty(sPGroup.DistributionGroupAlias))
{
sPGroup.DeleteDistributionGroup();
}
}
ErrorPage.CleanupInfoForMessageContainingLink(this.Context);
}
sPGroup.Update();
}
base.UpdateAdditionalProperties(sPGroup.ID);
return 0;
}
*** This one is the method that raise "Access Denied" exception and the consequent UI redirect to the Access Denied Exception. ***
// Microsoft.SharePoint.ApplicationPages.CBaseNewGroup
protected void UpdateAdditionalProperties(int groupId)
{
SPList siteUserInfoList = base.Web.SiteUserInfoList;
SPListItem itemById = siteUserInfoList.GetItemById(groupId);
string text = this.txtGrpDescription.Text;
itemById["Notes"] = text;
int num = 1;
while (true)
{
string text2 = base.Request.QueryString["FieldName" + num.ToString(CultureInfo.InvariantCulture)];
if (string.IsNullOrEmpty(text2))
{
break;
}
string value = base.Request.QueryString["FieldValue" + num.ToString(CultureInfo.InvariantCulture)];
itemById[text2] = value;
num++;
}
itemById.Update();
}
At this point I've checked with powershell the property "EffectiveBasePermissions" over UserInfo list, comparing the result with another Test Farm (which is working fine).
On Test Farm this collection was valued at FullMask. On Production Farm this collection was listing a number of base permissions.
The missing permission is the one related to the Update User Information.
From central admin, at WebApplication level, invoking "User Permissions" dialog, what I've discovered is that there was no flag on the basic permission "Edit Personal User Information".
Settings this flag=true on the webapplication affected will result in no more "Access Denied" redirect .
This bug/behavior has been verified on SharePoint 2010 SP1 + October 2012 CU.
Monday, February 18, 2013
Windows 2102 NLB and Loop Back Adapter
If you need to configure NLB on two or more IIS web server on Windows 2012, what you need is probably install "Microsoft LoopBack Adapter" network driver.
On this version of Windows, the correct name of this adapter is "Microsoft KM-TEST Loopback Adapter". If you need how to install this, you can check this kb article.
kb2777200
After sucessfully setup the adapter, you need to assign to IPv4 Stack on each front-end the same virtual IP Address, using 255.255.255.255 as network mask.
No need to define default gateway. No other protocol should be activated on this adapter. Only IPv4.
After that (no reboot required at all), you need to issue three command on each front-end in order to make everything working (this step was not necessary on Windows Server version prior 2008).
netsh interface ipv4 set interface "Ethernet" weakhostreceive=enabled
netsh interface ipv4 set interface "LoopBack" weakhostreceive=enabled
netsh interface ipv4 set interface "LoopBack" weakhostsend=enabled
Use instead of "Ethernet" and "LoopBack" the right names of your network interface.
Happy load balancing.
On this version of Windows, the correct name of this adapter is "Microsoft KM-TEST Loopback Adapter". If you need how to install this, you can check this kb article.
kb2777200
After sucessfully setup the adapter, you need to assign to IPv4 Stack on each front-end the same virtual IP Address, using 255.255.255.255 as network mask.
No need to define default gateway. No other protocol should be activated on this adapter. Only IPv4.
After that (no reboot required at all), you need to issue three command on each front-end in order to make everything working (this step was not necessary on Windows Server version prior 2008).
netsh interface ipv4 set interface "Ethernet" weakhostreceive=enabled
netsh interface ipv4 set interface "LoopBack" weakhostreceive=enabled
netsh interface ipv4 set interface "LoopBack" weakhostsend=enabled
Use instead of "Ethernet" and "LoopBack" the right names of your network interface.
Happy load balancing.
Wednesday, February 6, 2013
SharePoint 2010 - Problem in image result thumbnail within search result form a NON default Zone.
There is a problem on the preview of images that are displayed as a search result if this is carried out by an outer zone (therefore using an Alternate Access Mapping). The preview always points to the default AAM and as a result is not displayed.
Basically what needs to be done to solve the problem is to update the property "UseAAMMapping" of the managed property "PictureThumbnailURL."
To do this, simply run the powershell script below.
You do not need to re-crawl content.
The curious thing is that before setting the property to "true", if you check the value you see that is already set correctly.
You can read full story here:
http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/173bece0-1fac-43c3-ad2d-ef796cc8371a/
Basically what needs to be done to solve the problem is to update the property "UseAAMMapping" of the managed property "PictureThumbnailURL."
To do this, simply run the powershell script below.
$searchapp =
Get-SPEnterpriseSearchServiceApplication
(get-spenterprisesearchserviceapplication)
$property =
Get-SPEnterpriseSearchMetadataManagedProperty –SearchApplication $searchapp
–Identity "PictureThumbnailURL"
$property.UseAAMMapping =
$true
$property.Description = "Some
Description" # Need to update this for commit to work properly
$property.Update()
$searchapp.Update()
You do not need to re-crawl content.
The curious thing is that before setting the property to "true", if you check the value you see that is already set correctly.
You can read full story here:
http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/173bece0-1fac-43c3-ad2d-ef796cc8371a/
Labels:
AAM,
Alternate Access Mapping,
Search,
SharePoint 2010
SharePoint 2010 and 2013 convert License type
Often you need to enable the Enterprise feature on a farm originally installed with Standard key (or Trial).
Well, the Central Admin page set up to manage this upgrade will often give you the Text Box to insert the key "disabled" as well as the upgrade button to proceed.
There's another path to get this function. This is called "Enable Enterprise Features" in "Upgrade and Patch Management".
At this point you will prompt for the new key and you can proceed with the upgrade.
Well, the Central Admin page set up to manage this upgrade will often give you the Text Box to insert the key "disabled" as well as the upgrade button to proceed.
There's another path to get this function. This is called "Enable Enterprise Features" in "Upgrade and Patch Management".
At this point you will prompt for the new key and you can proceed with the upgrade.
Monday, February 4, 2013
Get Query String Parameter with JScript
In order to get client side query string parameter value, you can use this jscript function.
function getQuerystring(key, default_)
{
if (default_==null) default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
Usage:
var paramValue = getQuerystring('keytofindvalue');
You can optionally pass a default value to this function. In this case, if non existing parameter is founded in the query string, the function will return default_ value.
For more detail on this function, please take a look here:
http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx
function getQuerystring(key, default_)
{
if (default_==null) default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
Usage:
var paramValue = getQuerystring('keytofindvalue');
You can optionally pass a default value to this function. In this case, if non existing parameter is founded in the query string, the function will return default_ value.
For more detail on this function, please take a look here:
http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx
Friday, February 1, 2013
User Profile Service Provisioning Permissions
In order to successfully provision "User Profile Synchronization Service" on a SharePoint 2010 or a SharePoint 2013 you need specific permission.
1) FIM Account must have "Logon Locally" policy. Grant this using Local Security Policy on the server is receiving User Profile Synchronization Service provisioning;
2) SharePoint Timer Service account need to be local Administrator on target server because Provisioning Timer Job need to create Local Security Group and access with write permission to Windows Registry. After provisioning you can remove this user from local Administrators.
Important NOTE: Be sure that Regional Settings of the Domain User that is running SharePoint Timer Service are the same as Language ID of SharePoint Installation. In my case en-US.
You can check actual regional settings for that user opening PS with "run-as" using the inetrested user and issuing: Get-WinSystemLocale.
The error logged in trace log during service provisioning is:
UserProfileApplication.SynchronizeMIIS: Error updating users with FIM permissions: System.Runtime.Serialization.SerializationException: There was an error deserializing the object . String was not recognized as a valid DateTime. ---> System.FormatException: String was not recognized as a valid DateTime.
Reboot target machine and "try" to provision the service.
1) FIM Account must have "Logon Locally" policy. Grant this using Local Security Policy on the server is receiving User Profile Synchronization Service provisioning;
2) SharePoint Timer Service account need to be local Administrator on target server because Provisioning Timer Job need to create Local Security Group and access with write permission to Windows Registry. After provisioning you can remove this user from local Administrators.
Important NOTE: Be sure that Regional Settings of the Domain User that is running SharePoint Timer Service are the same as Language ID of SharePoint Installation. In my case en-US.
You can check actual regional settings for that user opening PS with "run-as" using the inetrested user and issuing: Get-WinSystemLocale.
The error logged in trace log during service provisioning is:
UserProfileApplication.SynchronizeMIIS: Error updating users with FIM permissions: System.Runtime.Serialization.SerializationException: There was an error deserializing the object . String was not recognized as a valid DateTime. ---> System.FormatException: String was not recognized as a valid DateTime.
Reboot target machine and "try" to provision the service.
Labels:
FIM,
SharePoint 2010,
SharePoint 2013,
User Profile Service
SharePoint Trace Logs Files 0kb
If you plan to use a low privilege account to run "SharePoint Tracing Service" (that is raccomanded), probably this will result in 0kb log files. This is due to lack of permission of this account to the LOG folder.
Instead of add the user directly to the folder you should add this account to a specific Windows Local Group named "Performance Log Users".
Once added the account, restart "SharePoint Tracing Service" in order to Apply changes.
From this point, Trace Log files will be correctly populate.
Instead of add the user directly to the folder you should add this account to a specific Windows Local Group named "Performance Log Users".
Once added the account, restart "SharePoint Tracing Service" in order to Apply changes.
From this point, Trace Log files will be correctly populate.
Subscribe to:
Posts (Atom)