Tuesday, December 17, 2013

SuiteBarBrandingElementHtml - How to change SharePoint label on top of every page

Every SharePoint 2013 Web Application has a specific property we can use to specify how SharePoint should render the label on top-left of every page.

This property is not exposed by the UI but you can change it using PowerShell.
The name of this property is: SuiteBarBrandingElementHtml

This property is a string property that accept any Html Element. So you can customize it in many way.

My typical use is for differentiate Developement Environment by Production ones.

For example you can type a PowerShell script like that to adjust Suite Bar for a quality environment:

$wa = Get-SPWebApplication -Identity "https://myfqdn.web.app"
$wa.SuiteBarBrandingElementHtml = "<div class=""ms-core-brandingText"">myfqdn.web.app <b>(quality)</b></div>"
$wa.Update()

That's all.

Friday, November 15, 2013

How To Export WSP SharePoint Solution from Solution Store with PowerShell

This is a simple script that can be usefull during migration of SharePoint from 2010 version to 2013 version if you are using ContentDB upgrade model.

This ps1 extract all wsp solution deployed to a SharePoint Farm to a specific folder on file system.

$destFolderName = "D:\Tmp\ExportedWSP"
foreach ($solution in Get-SPSolution)
{
    $id = $Solution.SolutionID
    $title = $Solution.Name
    $filename = $Solution.SolutionFile.Name

    try {
        $solution.SolutionFile.SaveAs("$destFolderName\$filename")
        Write-Host " – done" -foreground green
    }
    catch
    {
        Write-Host " – error : $_" -foreground red
    }
}

Run it on SharePoint Management Shell with Farm Admin permission.

Tuesday, November 5, 2013

Create Enterprise Search Service Application in SharePoint 2013 with Powershell

This note have the intent to give you a shortcut for a typical Enterprise Search Topology in SharePoint 2013 Small Farm.

This is basically a PowerShell script that help you to create from scrach an Enterprise Search Service Application (and its related Proxy) with following Topology:

Here's the script:

$PSSnapin = Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | Out-Null
#SET THIS PARAMETERS TO MEET YOUR Environement
$hostA = Get-SPEnterpriseSearchServiceInstance -Identity "applicationserver"
$hostB = Get-SPEnterpriseSearchServiceInstance -Identity "frontendserver1"
$hostC = Get-SPEnterpriseSearchServiceInstance -Identity "frontendserver2"

$serviceAppName = "Enterprise Search Service Application"
$dbServer = "SQLSERVERALIAS"
$searchServer = $serverName
$searchDBName = "SP2013_EnterpriseSearch"
$svcAppPoolName = "SharePoint Web Services System"
$indexLocation = "E:\SPSData\Index"
$searchCred = "DomainSearchServiceAccount"
$searchPwd = ConvertTo-SecureString -String 'DomainSearchServicePassword' -AsPlainText -Force

#END OF PARAMETER SECTION

Start-SPEnterpriseSearchServiceInstance -Identity $hostA
Start-SPEnterpriseSearchServiceInstance -Identity $hostB
Start-SPEnterpriseSearchServiceInstance -Identity $hostC


$hostA.DefaultIndexLocation = $indexLocation
$hostB.DefaultIndexLocation = $indexLocation
$hostC.DefaultIndexLocation = $indexLocation
 
#Wait for service OnLine on Every Host
$ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostA
while ($ss1.Status -ne "Online")
{
    Start-Sleep 10
    $ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostA
}
$ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostB
while ($ss1.Status -ne "Online")
{
    Start-Sleep 10
    $ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostB
}
$ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostC
while ($ss1.Status -ne "Online")
{
    Start-Sleep 10
    $ss1 = Get-SPEnterpriseSearchServiceInstance -Identity $hostC
}


$cred = Get-Credential $searchCred
$searchSvcAccount = Get-SPManagedAccount $cred.UserName -ErrorAction SilentlyContinue

if ($searchSvcAccount -eq $null)
{
    $searchSvcAccount = New-SPManagedAccount $cred
}

$searchSvc = Get-SPEnterpriseSearchServiceInstance -Local
if ($searchSvc -eq $null)
{
    throw "Unable to retrieve search service"
}

#Set Search Service parameter
$searchSvc | Set-SPEnterpriseSearchServiceInstance

if ($searchSvc.Status -ne "Online")
{
$searchSvc | Start-SPServiceInstance
}

$svc = Get-SPEnterpriseSearchService
Set-SPEnterpriseSearchService `
      -Identity $svc `
      -ServiceAccount $searchSvcAccount.UserName `
      -ServicePassword $searchPwd `
      -ContactEmail "
contactemail@domain.com" `
      -ConnectionTimeout "60" `
      -AcknowledgementTimeout "60" `
      -ProxyType "Default" `
      -PerformanceLevel "PartlyReduced"
  
  
$searchApp = Get-SPEnterpriseSearchServiceApplication $serviceAppName -ErrorAction SilentlyContinue
if ($searchApp -eq $null)
{
    $saAppPool = Get-SPServiceApplicationPool | where { $_.Name -eq $svcAppPoolName }
    $searchApp = New-SPEnterpriseSearchServiceApplication -Name $serviceAppName -ApplicationPool $saAppPool -DatabaseServer $dbServer -DatabaseName $searchDBName
}

#Declare New Topology
$ssa = Get-SPEnterpriseSearchServiceApplication
$newTopology = New-SPEnterpriseSearchTopology -SearchApplication $ssa

#Define all required components
New-SPEnterpriseSearchAdminComponent -SearchTopology $newTopology -SearchServiceInstance $hostA
New-SPEnterpriseSearchCrawlComponent -SearchTopology $newTopology -SearchServiceInstance $hostA
New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $hostA
New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $hostA
New-SPEnterpriseSearchIndexComponent -SearchTopology $newTopology -SearchServiceInstance $hostB -IndexPartition 0
New-SPEnterpriseSearchIndexComponent -SearchTopology $newTopology -SearchServiceInstance $hostC -IndexPartition 0
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $hostB
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $hostC

#Apply New Topology
Set-SPEnterpriseSearchTopology -Identity $newTopology

#Create Proyx for Service Application
$searchProxy = New-SPEnterpriseSearchServiceApplicationProxy -Name "$serviceAppName Proxy" -SearchApplication $searchApp


Or you can download the ps1 script here.

Update SharePoint 2013 to August 2013 CU

If you are planning to upgrade your SharePoint 2013 Farm to August 2013 Cumulative Update, consider following consideration:

1 - Go to this link to Request download for the CU
1.a - For SharePoint foundation the link is this one kb2817517.
1.b - For SharePoint Server the link is this one kb2817616.

2 - You already heve installed March 2013 SharePoint 2013 Public Update (PU)

3 - The update take a lot of time to complete. If you want to minimize this, read this interesting article "Why SharePoint 2013 Cumulative Update takes 5 hours to install?".

4 - After the update, you obviously need to run SharePoint Configuration Wizard. Using standard psconfigwiz.exe the update is performed in timer job. If you are experiencing issues using this approach, you can run psconfig.exe from command line with this parameters:

PSConfig.exe -cmd upgrade -inplace b2b -wait -force -cmd applicationcontent -install -cmd installfeatures

Note the -wait parameter that tell psconfig.exe to run the upgrade process not in the timerjob process, but in current process session.

The -force parameter tell psconfig.exe to ignore previous Upgrade Timer Job defined in configuration database.

In my case, running the upgrade in timerjob cause the upgrade process to be stucked on 10%.

Monday, November 4, 2013

Slow SharePoint Start Up - Disable CLR Check with PowerShell

If you are experiencing slow SharePoint Application Pool Start Up, probably what you need is to remove CLR Check for Assembly Signing.

I've found a very usefull PowerShell script from marvelous AutoSPInstaller (https://autospinstaller.codeplex.com/) that do it for you.

This function disable CLR Check from Windows Registry and from machine.config.

Here's the snippet:

Function DisableCRLCheck()
{
 Write-Host -ForegroundColor White " - Disabling Certificate Revocation List (CRL) check..."
 Write-Host -ForegroundColor White "  - Registry..."
 New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS -ErrorAction SilentlyContinue | Out-Null
 New-ItemProperty -Path "HKU:\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing" -Name State -PropertyType DWord -Value 146944 -Force | Out-Null
 New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing" -Name State -PropertyType DWord -Value 146944 -Force | Out-Null
 Write-Host -ForegroundColor White "  - Machine.config..."
 ForEach($bitsize in ("","64"))
 {
  # Added a check below for $xml because on Windows Server 2012 machines, the path to $xml doesn't exist until the .Net Framework is installed, so the steps below were failing
  $xml = [xml](Get-Content "$env:windir\Microsoft.NET\Framework$bitsize\v2.0.50727\CONFIG\Machine.config" -ErrorAction SilentlyContinue)
  if ($xml)
  {
   If (!$xml.DocumentElement.SelectSingleNode("runtime")) {
    $runtime = $xml.CreateElement("runtime")
    $xml.DocumentElement.AppendChild($runtime) | Out-Null
   }
   If (!$xml.DocumentElement.SelectSingleNode("runtime/generatePublisherEvidence")) {
    $gpe = $xml.CreateElement("generatePublisherEvidence")
    $xml.DocumentElement.SelectSingleNode("runtime").AppendChild($gpe) | Out-Null
   }
   $xml.DocumentElement.SelectSingleNode("runtime/generatePublisherEvidence").SetAttribute("enabled","false") | Out-Null
   $xml.Save("$env:windir\Microsoft.NET\Framework$bitsize\v2.0.50727\CONFIG\Machine.config")
  }
  else
  {
   if ($bitsize -eq "") {$bitsize = "32"}
   Write-Warning "$bitsize-bit machine.config not found - could not disable CRL check."
  }
 }
 Write-Host -ForegroundColor White " - Done."
}


Thanks again to autospinstaller for his wanderfull job.

Thursday, October 24, 2013

Cannot Create Web Application from Central Administration in SharePoint 2013 - Cannot display Web Page

If you are experiencing failure during creation phase of a new Web Application in SharePoint 2013, probably your environment is under capacity planning raccomandations.

What happen is that the process take a very long time but not everything is done in order to have a correctly created web application.

In addition Central Administration UI show you a pop-up "Cannot display web page".

This is due to a time-out in the application pool ping feature.

You can fix this by changing default value for the application pool from 90 to another reasonable value (in my case I've used 360).

Open IIS Manager, go to Application Pools node and then select "Set Application Pool Defaults ...".

Change "Ping Maximum Response Time (seconds)" to a Greater value.

This Application Pool property is available in IIS 7 and greater.

This picture show you this property in IIS Manager.

Tuesday, September 17, 2013

Programmatically Create Alert for FBA User in SharePoint Claims Web Application

Assuming that you are using email Address as username for a claims authenticated SharePoint Web Application, you can use this simple code to programmatically create an Alert for a specific user.

using (SPSite site = new SPSite("http://fqdn.sharepoint.claims.webapp"))
{
 SPIisSettings settings = site.WebApplication.IisSettings[SPUrlZone.Default];
 MembershipProvider membership = System.Web.Security.Membership.Providers[settings.FormsClaimsAuthenticationProvider.MembershipProvider];
   
 using (SPWeb web = site.OpenWeb())
 {
  SPUser user = web.SiteUsers["i:0#.f|" + membership.Name + "|" + Email];
  SPAlert newAlert = user.Alerts.Add();
  newAlert.AlertType = SPAlertType.List;
  newAlert.List = web.Lists["List Name"];
  newAlert.EventType = SPEventType.All;
  newAlert.AlertFrequency = SPAlertFrequency.Immediate;
  //passing true to Update method will send alert confirmation mail
  newAlert.Update(false); // will not send alert confirm email
  //newAlert.Update(true);  // will send alert confirm email to subscribed user
 }
}


Hope this can help.

Wednesday, August 7, 2013

Windows Server 2012 Windows Update very slow

If you are unable to perform (or it's very very slow) Windows Update on Windows Server 2012, try to import proxy settings using this command (with elevated permission):

netsh winhttp import proxy source=ie

Be sure, before execute the command that IE is able to navigate to internet.

This solved the issues for my environment.

Tuesday, July 30, 2013

SharePoint 2007 and ADFS with "custom" SharePointClaimsMembershipProvider

As requirements for a customer project, we need to migrate a SharePoint 2007 (MOSS 2007) from ADAM Authentication to ADSF 2.0 Authentication.
MOSS is configured to use Form Based Authentication (FBA) using ootb LDAP Authentication Provider.

Now, in order to use ADFS to authenticate MOSS users what we need is to install and configure "Microsoft Federation Extensions For SharePoint 3.0".

The setup install an assembly in GAC that is Microsoft.IdentityModel.SharePoint12.dll.
An utility is also provided in order to configure a specific zone of our Sharepoint Web Application.

This utility change the web.config of Central Administration and the web.config of our Web Application, adding information about this new Authentication Provider.

The name attribute is configured as "SharePointClaimsMembershipProvider".
This is the interessed session:

 <membership defaultProvider="SharePointClaimsMembershipProvider">
      <providers>
        <add name="SharePointClaimsMembershipProvider" type="Microsoft.IdentityModel.SharePoint12.SharePointClaimsMembershipProvider, Microsoft.IdentityModel.SharePoint12, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </providers>
    </membership>


So the point: in our environment users where configured using a different name as Authentication Provider and we do not want to migrate every users defined in the SharePoint web application. Simply change name attribute of the autnetication provider in both web.config and in the specific session of Central Administration and ... voilà ... Web App is broken.

The message is "Cannot Find Default Provider".

But my web.config is configured as follow:

 <membership defaultProvider="externalusers">
      <providers>
        <add name="externalusers" type="Microsoft.IdentityModel.SharePoint12.SharePointClaimsMembershipProvider, Microsoft.IdentityModel.SharePoint12, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </providers>
    </membership>


And for me the (only) provider is correctly defined.
So, where is the trick?

I've done rev-eng of the assembly and what I've found is that the Init Method of the class simply call the .base method of MembershipProvider base class using a constant.

This costant is "SharePointClaimsMembershipProvider". So this is the reason of the failure. The init method of the class ignore the name attribute we've defined in web.config and it use the above constant.

To be able to use our own membership provider name you need to change the init method of the Microsoft class to use the name that the .net framework use to inizialize the provider. So I've changed the method in this way.

  public override void Initialize(string name, NameValueCollection config)
  {
            //base.Initialize("SharePointClaimsMembershipProvider", config);
            base.Initialize(name, config);
  }

 
There's also another method you need to change. It's "FindUsersByEmail" that also use the constant "SharePointClaimsMembershipProvider".

I've recompiled everything using a different signature file and changing the assembly version.
Finally I was able to use "default" .net framework behaviour whit ADFS and MOSS 2007 ;) and this save me from migrate every users ACL in Sharepoint.

HowTo List or Export Installed Windows Updates

In order to retrieve or export installed Windows Updates you need to execute this command using normal Command Prompt (with Admin privilege):

wmic qfe get /format:HTABLE >D:\Temp\InstalledUpdates.htm

All available export format are:

CSV; HFORM; HTABLE; LIST; MOF; RAWXML

Use the one you prefer.

The output should be something like this:


Thursday, July 25, 2013

HowTo Get Query String Parameters using Jscript Function

A simple function that give you ability to retrieve query string parameters client side using javascript.

function getQueryStringParameter( name )

 name = name.replace(/[\[]/,"
\\\[").replace(/[\]]/,"\\\]"); 
 var regexS = "[\\?&]"+name+"=([^&#]*)"; 
 var regex = new RegExp( regexS ); 
 var results = regex.exec( window.location.href ); 
 if( results == null )   
  return ""; 
 else   
  return results[1];
}

So, in order to retrieve a parameter, just type:

var paramValue = getQueryStringParameter('parameterName');

Wednesday, July 24, 2013

HowTo Change FEDAUTH cookie to be In-Memory Session in SharePoint and Set Lifetime of STS

If you are implementing a Claims SharePoint WebApplication with Form Login and you want to force login after a specific period of time, what you need is to change behavior of Security Token Service (STS).
Changing attributes of <forms> tag inside webapp web.config does not affect because SharePoint manage FEDAUTH cookie internally, based on STS configuration.

By default, SharePoint store this authentication cookie on disk. So the behavior is that when a user close browser after authentication and re-open the same web app, no credential are required. This is due to default UseSessionCookies property value of STS that is $false.

To change this use following PS script:

$sts = Get-SPSecurityTokenServiceConfig
$sts.UseSessionCookies = $true
$sts.Update()
iisreset


This store FEDAUTH cookie in memory.

In order to control timespan for each session you can change STS property in this way.

$sts = Get-SPSecurityTokenServiceConfig
$sts.UseSessionCookies = $true
$sts.CookieLifetime = (New-TimeSpan -Minutes 5)
$sts.FormsTokenLifetime = (New-TimeSpan -Minutes 5)
$sts.ServiceTokenLifetime = (New-TimeSpan -Minutes 5)
$sts.Update()
iisreset

Monday, July 22, 2013

Create Self Service Certificate for Quality/Test Environment

In order to be able to create a Root Certification Authority and some kind of Child Certificate for test and development environment, you can use Makecert.exe.

These command create:

1- Root CA
makecert -n "CN=My Certificate Root" -a sha1 -r -sv My.pvk MyCA.cer -ss Root -sr localMachine

2 - SSL Binding for IIS
makecert -pe -n "CN=WIN2012VS" -sr LocalMachine -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.1 -iv My.pvk -ic MySSL.cer

3 - Client Cert for IIS Client Authentication
makecert -pe -n "CN=My User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.2 -iv My.pvk -ic MyUser.cer

You can then export pfx of generated Client Cert in order to be able to distribute both Root CA and Client Certificate used for authentication. To do this, use standard Windows Certificate Snap In of MMC.

More info about all available command and switch of Makecert.exe utility please read this article.

Certificate Creation Tool (MSDN)

Monday, July 8, 2013

How to Get SharePoint Farm Build Version with PowerShell

This is just a reminder for a PowerShell script that give you exactly Build Version of your SharePoint Farm.

This commandlet is valid for both 2010 and 2013 version of SharePoint.
It return non the level of installed SharePoint build, but the actual running SharePoint version.
This depends to the fact you have run SharePoint Configuration Wizard after a patch installation or not.

Review Database Status using the link in Central Administration:

http://sharepointCAUrl:port/_admin/DatabaseStatus.aspx

The command is (Open SharePoint Management Shell as Farm Admin):

(Get-spfarm).buildversion

The Output should be like this:

Major  Minor  Build  Revision
-----  -----  -----  --------
14     0      6134   5000

Tuesday, June 25, 2013

How to change MaxReceivedMessageSize for Client Obejct Model in SharePoint 2010 2013

If you are using SharePoint client Object Model and you need to change max size of the message you need to pass to Client.svc, what you probably need is to increase the default value. This can occour for example if you are uploading files to a remote SharePoint using client object model.

The message you are receiving when executing query with client obejct model should be something similar to this: "The request message is too big. The server does not allow messages larger than 2097152 bytes."

The property is MaxReceivedMessageSize of ClientRequestServiceSettings.

Default value is 2MB (2097152 bytes).

Use this PowerShell script (from SharePoint Management Shell in Administrative mode with a Farm Administrative Account) to change this value.

In the example this is set to 2GB.

$ws = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$ws.ClientRequestServiceSettings.MaxReceivedMessageSize = 2147483647
$ws.Update()


Another option is to create a Farm Scoped Feature with this feature receiver:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
   SPWebService contentService = SPWebService.ContentService;

   /* Must set this to -1, else, the MaxReceivedMessageSize value for
   SPWebService.ContentService.WcfServiceSettings["client.svc"] will not be used.*/
   contentService.ClientRequestServiceSettings.MaxReceivedMessageSize = -1;

   // SPWcfServiceSettings has other Properties that you can set.
   SPWcfServiceSettings csomWcfSettings = new SPWcfServiceSettings();
   csomWcfSettings.MaxReceivedMessageSize = 2147483647; // 2048MB
   contentService.WcfServiceSettings["client.svc"] = csomWcfSettings;

   contentService.Update();
}


More at: http://msdn.microsoft.com/en-us/library/ff599489.aspx

Tuesday, June 11, 2013

Add and Remove an Assembly from the GAC using PowerShell

If you need to add or remove an assembly from Global Assembly Cache without installing SDK o VS and you don't want to disable UAC, you can do that using a simple PowerShell script.

Be sure to execute PowerShell in Administrative mode.

To add an Assembly to the GAC

Set-location "c:\temp"
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
$publish.GacInstall("c:\temp\myassembly.dll")


To remove an Assembly from the GAC

Set-location "c:\temp"
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
$publish.GacRemove("c:\temp\myassembly.dll")

HowTo Clear SharePoint Timer Job Cache

Often during SharePoint development can be usefull to clear Timer Job Cache.
In order to do that we need to do this:

  • Stop Windows SharePoint Timer Service from Windows Services
  • Open C:\ProgramData\Microsoft\SharePoint\Config\<<GUID>> folder
  • Delete all the XML files inside the GUID folder.
  • Open the Cache.ini file and change the value to 1.
  • Save Cache.ini file
  • Restart Windows SharePoint Timer Service from Windows Services

After restarting Windows SharePoint Timer Service you can see that the cache will be repopulate (quite resource expensive activity).

Do that on every SharePoint server in the farm.

Thursday, May 9, 2013

SharePoint 2013 - "Database is in compatibility range and upgrade is recommended" for BDCServiceDatabase after March 2013 Upgrade

On a SharePoint 2013 Farm, after upgrading to Public Update March 2013 (see this article), you can see that BDCServiceDatabase in in compatibility range.

You can see this going through Central Admin > Upgrade and Migration > Review Database Status.
Configuration Wizard or PSCONFIG upgrade does not fix this compatibility issues.

In order to fix it, you need to reprovision BdcServiceDatabase using the following PS script.

(Get-SPDatabase | ?{$_.type -eq "Microsoft.SharePoint.BusinessData.SharedService.BdcServiceDatabase"}).Provision()

Now all yours SharePoint DB are in "no action required" status.

Tuesday, April 23, 2013

System.Runtime.InteropServices.COMException: Illegal operation attempted on a registry key that has been marked for deletion. (Exception from HRESULT: 0x800703FA) - SharePoint 2013 Search

I'm building a SharePoint 2013 Farm with a quite complex search Topology.
My Topology is shown in this picture.



I'm using Windows Server 2012 as OS and I'm experiencing this strange behavior.
Basically, when I chose to edit content source from Central Administration, I receive an error.

The error is COM related:

System.Runtime.InteropServices.COMException: Illegal operation attempted on a registry key that has been marked for deletion. (Exception from HRESULT: 0x800703FA)

To solve this issue, you can try to change a policy that told Windows to "forcefully unload the user registry at user logoff ". I've changed this policy on every server in my Topology but I suppose that only Admin components are affected by this behavior.

The policy can be changed using gpedit.msc.

The path of the policy is:
Computer Configuration->Administrative Templates->System-> UserProfiles

The policy is: “Do not forcefully unload the user registry at user Logoff”
Set this to "enabled".

Thanks to this article that point me to the solution. The article is about Windows Server 2008 but also Apply to Windows Server 2012.

Thursday, March 21, 2013

SharePoint 2013 Public Update March 2013


Today is available a PU – Public Update - (march 2013) for SharePoint 2013.

You need to install it if you plan to update your farm in the future. ;)
Here you are the links to official KB article and the links to direct download.
  • KB 2768000 - SharePoint Foundation 2013
  • KB 2767999 - SharePoint Server 2013
  • KB 2768001 - Project Server 2013


Server package (about 1.6GB!!!! in english version) contains Foundation Package.
Project package contains Server Package.

Enjoy!

Wednesday, March 13, 2013

Create Self Signed Certificate for IIS 6 - SelfSSL.exe

In order to create a Self Signed certificate for a web application running on a IIS 6.0 web server, we can use SELFSSL.exe utility.

This exe can be normally found on this directory:

C:\Program Files\IIS Resources\SelfSSL

Issue this command:

selfssl /S:<site ID of web application> /V:999999

Confirm eventually the replacement of the existing SSL Certificate and you are done.

This was usefull for me because self signed certificate of my "Office Server Web Service" web application of MOSS 2007 was Expired.

The error logged in trace log accessing User Profile page of SharedService Provider was:

Fail to obtain crawl status. System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

The aspx page exception was:

An error has occurred while accessing the SQL Server database or the Office SharePoint Search service.

This is the screenshot.

Thursday, March 7, 2013

SharePoint - Upgrade Classic Content DB 2010 to Claims Web Application 2013

Just as reminder for me, when you need to attach a content database that come from a SharePoint 2010 web application with Classic Mode Authentication Schema to a SharePoint 2013 web application that use claims (default) authentication, after the attach (that can be done either with powershell or the oldstyle (ed) stsadm.exe) you need to convert users from classic to claims.

This can be done with this PS command:

Convert-SPWebApplication -Identity  http://webappurl.with.fqdn -To Claims -RetainPermissions -Force

even if the web app is already in claims auth.

Thursday, February 28, 2013

Image Handling in SharePoint 2013 and IE9/10 - GIF Image in Document Library not Showed

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

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.

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.

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.

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

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.

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

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.

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.

Thursday, January 31, 2013

Enable NetFx3 on Windows Server 2012

If you are planning to install SQL Server 2012 on Windows Server 2012, NetFx3 is a pre-requisite.
In order to intall NetFx3 what you need is to Mount installation ISO of Windows Server 2012 and run this command at prompt:

dism /online /enable-feature /all /featurename:NetFx3 /source:f:\sources\sxs

where f: is the letter of mounted ISO.

Setup will complete sucessfully and you can install SQL Server 2012.

Friday, January 25, 2013

Reporting Services SharePoint Integrated - Permission Consideration

On MSDN there's a very usefull article about permission mapping between SharePoint and Reporting Services in Integrated Mode.

One things to consider is that if you wanna create a Subscription over a Report in a Report Library what you need is at least this flag in the permission level binded to the user (or SharePoint Group).

At Site Level you need: Manage Alerts
At List  Level you need: Create Alerts (+ obviously Read access)

The article is readable here:

Site and List Permission Reference for Report Server Items

SQL Function to Strip HTML String

I've found this simple SQL script that create a SQL Function that receive an HTML varchar(max) string in input and return a linear flat Text String (varchar(max)) without HTML markup.
This can be usefull if you plan to store HTML in SQL column and you need to return a plain text.

CREATE FUNCTION [dbo].[StripHTML]
 (@HTMLText VARCHAR(MAX))
 RETURNS VARCHAR(MAX)
 AS
 BEGIN
 DECLARE @Start INT
 DECLARE @End INT
 DECLARE @Length INT
 SET @Start = CHARINDEX('<',@HTMLText)
 SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
 SET @Length = (@End - @Start) + 1
 WHILE @Start > 0
 AND @End > 0
 AND @Length > 0
 BEGIN
  SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
  SET @Start = CHARINDEX('<',@HTMLText)
  SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
  SET @Length = (@End - @Start) + 1
 END
 RETURN LTRIM(RTRIM(@HTMLText))
 END

This just for my note and reminder.

Excecute rdlc Reports server side

In order to be able to render a rdlc report at server Runtime you need to install this Redistribuible package.

There are different version:

Microsoft Report Viewer 2012 Runtime – BETA
Microsoft Report Viewer 2010 Redistributable Package
Microsoft Report Viewer Redistributable 2008

For more about rendering rdlc reports you can check this usefull article.

Render a .rdlc reports in Excel format.

SQL Function to Split a varchar Field

I've found on the web but I cannot remember where, a very usefull SQL Function used to strip an input string. Return parameter is a table.

CREATE FUNCTION [dbo].[Split] (@s varchar(512), @sep char(1))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )

The limit of this function is that you cannot use OPTION (MAXRECURSION nnn) to change default 100 limit in SQL recusrsion.

Wednesday, January 23, 2013

SharePoint 2010 - Browser File Handling Bug

There is a flag web application level that allows you to manage how SharePoint 2010 handles opening of documents other than Office.

You can force the download on the client (strict mode - this is the default) rather than directly open the document (permissive).

The setting works as described except that in a case:

- The document library is created from a site template (wsp solution).

In this case, all Document Library in the instanziated site have the property "BrowserFileHandling" set to Strict, ignoring the settings of the webapplication.

With this simple powershell script to run through the SharePoint Management Shell, you can reset all the document library of all the web for a specific site collection to the desired behavior.



$site=Get-SPSite http://sitecollectionurl
$webs=$site.AllWebs


foreach($web in $webs)
{
 $web

 foreach($list in $web.Lists)
 {
  $list.BrowserFileHandling = "Permissive"
  $list.Update()
 }
}
 
 

Forefront Identity Manager - Schema validation failed

This post want to share my experience about "Schema Validation Failed" error logged every minute on the Application Log, associated to FIM Service of SharePoint 2010.

The error detail is:

Log Name:      Application
Source:        Forefront Identity Manager
Date:          23/01/2013 15:42:01
Event ID:      3
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      xxxxxxx.xxx.xxx
Description:
System.Data.ConstraintException: Schema validation failed.
Event Xml:
<Event xmlns="
http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Forefront Identity Manager" />
    <EventID Qualifiers="0">3</EventID>
    <Level>2</Level>
    <Task>0</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2013-01-23T14:42:01.000000000Z" />
    <EventRecordID>556000</EventRecordID>
    <Channel>Application</Channel>
    <Computer>xxxxxxx.xxx.xxx</Computer>
    <Security />
  </System>
  <EventData>


Immediatly after this error, another more detailed is logged on the App log.
The second error detail is:

Log Name:      Application
Source:        Forefront Identity Manager
Date:          23/01/2013 15:42:01
Event ID:      3
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      xxxxxxx.xxx.xxx
Description:
Microsoft.ResourceManagement: System.Data.ConstraintException: Schema validation failed.
   at Microsoft.ResourceManagement.Utilities.ExceptionManager.ThrowException(Exception exception)
   at Microsoft.ResourceManagement.ActionProcessor.ActionDispatcher.ProcessInputRequest(RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.ExecuteAction(RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.ExecuteAction[ResponseBodyType](RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.DispatchRequest[ResponseBodyType](RequestType request, Guid requestIdentifier, Object redispatchSingleInstanceKey)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.DispatchRequest[ResponseBodyType](RequestType request)
   at Microsoft.ResourceManagement.WebServices.ResourceManagementService.Create(Message request)
Event Xml:
<Event xmlns="
http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Forefront Identity Manager" />
    <EventID Qualifiers="0">3</EventID>
    <Level>2</Level>
    <Task>0</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2013-01-23T14:42:01.000000000Z" />
    <EventRecordID>556001</EventRecordID>
    <Channel>Application</Channel>
    <Computer>xxxxxxx.xxx.xxx</Computer>
    <Security />
  </System>
  <EventData>
    <Data>Microsoft.ResourceManagement: System.Data.ConstraintException: Schema validation failed.
   at Microsoft.ResourceManagement.Utilities.ExceptionManager.ThrowException(Exception exception)
   at Microsoft.ResourceManagement.ActionProcessor.ActionDispatcher.ProcessInputRequest(RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.ExecuteAction(RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.ExecuteAction[ResponseBodyType](RequestType request)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.DispatchRequest[ResponseBodyType](RequestType request, Guid requestIdentifier, Object redispatchSingleInstanceKey)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.DispatchRequest[ResponseBodyType](RequestType request)
   at Microsoft.ResourceManagement.WebServices.ResourceManagementService.Create(Message request)</Data>
  </EventData>
</Event>
    <Data>System.Data.ConstraintException: Schema validation failed.</Data>
  </EventData>
</Event>


After a lot of research, verbose logging, and the use of this usefull utility founded on Codeplex (FIMQueryTool - thanks a lot to the author), I was able to have more datail about the Failing Request.

The problem was related to a recently change of the permission of my SharePoint User Profile Service Application.

Basically I've garanted "Edit Profile permission" to a specific Active Directory Security Group.

This AD Security Group contains a blank in "PreWindows 2000 Name".

This blank was causing FIM Service to fail in validating Schema during the process of the Request related to this AD Group.

Removing the blank will fix everything.

I don't know if this can be considered a Bug or not. We can see if further SharePoint 2010 Cumulative Update or Service Pack will fix it.

This behavior has been discovered using SP1 + June 2012 Cumulative Update (kb2687299).

Monday, January 21, 2013

From SharePoint 2010 to 2013 - Changes

During evaluation impact of migration from a SharePoint 2010 Farm to a SharePoint 2013 farm you need to consider what's changed between the two version of the Platform.

TechNet has a good article that explain all the differences, the reason for changes and the eventually migration path (if apply):

Changes from SharePoint 2010 to SharePoint 2013

One important things to consider is that ther's no plan to continue support Document Workspace and Meeting Workspace. Infact, migrated site will continue to work due to the presence of web template, but furter creation based on these templates are not supported. These templates will be removed completely from the next major release of SharePoint.

The feature of creating Meeting Workspace from Outlook 2013 has been removed.

Friday, January 18, 2013

How To Create a Slide Library in SharePoint 2013

In SharePoint 2013 there is no Slide Library listed when you choose to add an App.
This feature is still present.

To create a Slide Library in SharePoint 2013 you need to navigate to

http://yourwebappname/yoursitename/_layouts/15/slnew.aspx?FeatureId={0be49fe9-9bc9-409d-abf9-702753bd878d}&ListTemplate=2100

I've tested it on a RTM version of SharePoint 2013 and it works.

This library seems to be the same we had on SharePoint 2010. Also FeatureId is the same as in SharePoint 2010.