SharePoint 2013 search open in client


March 26, 2014 - 16:26, by Steven Van de Craen - 1 Comments

Issue

SharePoint 2013 search results uses Excel Calculation Services to open workbooks found in the search results, despite having "open in client" specified on the Document Library and/or the Site Collection level. Notice the URL pointing to _layouts/xlviewer.aspx at the bottom of the screen. In this scenario I only have SharePoint Server 2013 installed without any Office Web Apps servers.
Searching a workbook

 

Initial solution

In my previous encounter with this issue I used a custom Search Result Type with Display Template in order to control the link that is rendered for the search result item.

Item_Excel_Client.html

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"> 
<head>
<title>Excel Client Item</title>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">Displays a result tailored for Microsoft Excel documents.</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
<mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title','Path':'Path','Description':'Description','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime','CollapsingStatus':'CollapsingStatus','DocId':'DocId','HitHighlightedSummary':'HitHighlightedSummary','HitHighlightedProperties':'HitHighlightedProperties','FileExtension':'FileExtension','ViewsLifeTime':'ViewsLifeTime','ParentLink':'ParentLink','FileType':'FileType','IsContainer':'IsContainer','ServerRedirectedURL':'ServerRedirectedURL','ServerRedirectedEmbedURL':'ServerRedirectedEmbedURL','ServerRedirectedPreviewURL':'ServerRedirectedPreviewURL'</mso:ManagedPropertyMapping>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>
<body>
    <div id="Item_Excel_Client">
<!--#_ 
        if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
            var id = ctx.ClientControl.get_nextUniqueId();
            var itemId = id + Srch.U.Ids.item;
            var hoverId = id + Srch.U.Ids.hover;
            var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Excel_HoverPanel.js";
            $setResultItem(itemId, ctx.CurrentItem);
            ctx.CurrentItem.csr_Icon = Srch.U.getIconUrlByFileExtension(ctx.CurrentItem);
            ctx.CurrentItem.csr_OpenApp = "excel";
            ctx.CurrentItem.csr_Path = ctx.CurrentItem.Path;
            ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
            ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();
_#-->
            <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="ExcelItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">
                _#=ctx.RenderBody(ctx)=#_                
                <div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>
            </div>
<!--#_ 
        } 
_#-->
    </div>
</body>
</html>

Item_Excel_Client.js

/* This file is currently associated to an HTML file of the same name and is drawing content from it.  Until the files are disassociated, you will not be able to move, delete, rename, or make any other changes to this file. */

function DisplayTemplate_89a1689efe684e93be8c5bdaa1e46b07(ctx) {
  var ms_outHtml=[];
  var cachePreviousTemplateData = ctx['DisplayTemplateData'];
  ctx['DisplayTemplateData'] = new Object();
  DisplayTemplate_89a1689efe684e93be8c5bdaa1e46b07.DisplayTemplateData = ctx['DisplayTemplateData'];

  ctx['DisplayTemplateData']['TemplateUrl']='~sitecollection\u002f_catalogs\u002fmasterpage\u002fDisplay Templates\u002fSearch\u002fItem_Excel_Client.js';
  ctx['DisplayTemplateData']['TemplateType']='Item';
  ctx['DisplayTemplateData']['TargetControlType']=['SearchResults'];
  this.DisplayTemplateData = ctx['DisplayTemplateData'];

  ctx['DisplayTemplateData']['ManagedPropertyMapping']={'Title':['Title'], 'Path':['Path'], 'Description':['Description'], 'EditorOWSUSER':['EditorOWSUSER'], 'LastModifiedTime':['LastModifiedTime'], 'CollapsingStatus':['CollapsingStatus'], 'DocId':['DocId'], 'HitHighlightedSummary':['HitHighlightedSummary'], 'HitHighlightedProperties':['HitHighlightedProperties'], 'FileExtension':['FileExtension'], 'ViewsLifeTime':['ViewsLifeTime'], 'ParentLink':['ParentLink'], 'FileType':['FileType'], 'IsContainer':['IsContainer'], 'ServerRedirectedURL':['ServerRedirectedURL'], 'ServerRedirectedEmbedURL':['ServerRedirectedEmbedURL'], 'ServerRedirectedPreviewURL':['ServerRedirectedPreviewURL']};
  var cachePreviousItemValuesFunction = ctx['ItemValues'];
  ctx['ItemValues'] = function(slotOrPropName) {
    return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName)
};

ms_outHtml.push('',''
); 
        if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
            var id = ctx.ClientControl.get_nextUniqueId();
            var itemId = id + Srch.U.Ids.item;
            var hoverId = id + Srch.U.Ids.hover;
            var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Excel_HoverPanel.js";
            $setResultItem(itemId, ctx.CurrentItem);
            ctx.CurrentItem.csr_Icon = Srch.U.getIconUrlByFileExtension(ctx.CurrentItem);
            ctx.CurrentItem.csr_OpenApp = "excel";
            ctx.CurrentItem.csr_Path = ctx.CurrentItem.Path;
            ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
            ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();
ms_outHtml.push(''
,'            <div id="', $htmlEncode(itemId) ,'" name="Item" data-displaytemplate="ExcelItem" class="ms-srch-item" onmouseover="', ctx.currentItem_ShowHoverPanelCallback ,'" onmouseout="', ctx.currentItem_HideHoverPanelCallback ,'">'
,'                ',ctx.RenderBody(ctx),'                '
,'                <div id="', $htmlEncode(hoverId) ,'" class="ms-srch-hover-outerContainer"></div>'
,'            </div>'
); 
        } 
ms_outHtml.push(''
,'    '
);

  ctx['ItemValues'] = cachePreviousItemValuesFunction;
  ctx['DisplayTemplateData'] = cachePreviousTemplateData;
  return ms_outHtml.join('');
}
function RegisterTemplate_89a1689efe684e93be8c5bdaa1e46b07() {

if ("undefined" != typeof (Srch) &&"undefined" != typeof (Srch.U) &&typeof(Srch.U.registerRenderTemplateByName) == "function") {
  Srch.U.registerRenderTemplateByName("Item_Excel_Client", DisplayTemplate_89a1689efe684e93be8c5bdaa1e46b07);
}

if ("undefined" != typeof (Srch) &&"undefined" != typeof (Srch.U) &&typeof(Srch.U.registerRenderTemplateByName) == "function") {
  Srch.U.registerRenderTemplateByName("~sitecollection\u002f_catalogs\u002fmasterpage\u002fDisplay Templates\u002fSearch\u002fItem_Excel_Client.js", DisplayTemplate_89a1689efe684e93be8c5bdaa1e46b07);
}

}
RegisterTemplate_89a1689efe684e93be8c5bdaa1e46b07();
if (typeof(RegisterModuleInit) == "function" && typeof(Srch.U.replaceUrlTokens) == "function") {
  RegisterModuleInit(Srch.U.replaceUrlTokens("~sitecollection\u002f_catalogs\u002fmasterpage\u002fDisplay Templates\u002fSearch\u002fItem_Excel_Client.js"), RegisterTemplate_89a1689efe684e93be8c5bdaa1e46b07);
}

 

Then I pushed the Display Template and Result Type automatically to all Site Collections, because I wanted a uniform experience.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction:SilentlyContinue

function DropFile([Microsoft.SharePoint.SPWeb]$spweb, [string]$fileName, [byte[]]$fileContents)
{
    $spfolderUrl = $spweb.Url + "/_catalogs/masterpage/Display Templates/Search";
    $spfolder = $spweb.GetFolder($spfolderUrl);
    $spfile = $spweb.GetFile("$spfolderUrl\$fileName");
    
    if ($spfile.Exists)
    {
        $spfile.CheckOut();
    }

    $spfile = $spfolder.Files.Add($fileName, $fileContents, $true);
    
    if ($spfile.CheckOutType -ne "None")
    {
        $spfile.CheckIn("");
    }

    $spfile.Publish("");
    $spfile.Approve("");
    
    Write-Host " > Display Template Provisioned."
    
    return $spfile;
}

function CreateSearchResultType([Microsoft.SharePoint.SPWeb]$spweb, [string]$spfileUrl)
{
    $ssa = Get-SPEnterpriseSearchServiceApplication
    $owner = Get-SPEnterpriseSearchOwner -Level SPSite -SPWeb $spweb
    $excelRIT = Get-SPEnterpriseSearchResultItemType -Owner $owner -SearchApplication $ssa | Where Name -eq "Microsoft Excel"
    $rules = $excelRIT.Rules
    $dispProps = $excelRIT.DisplayProperties
    $sptemplateUrl = "~sitecollection/$spfileUrl";
    
    Write-Host $sptemplateUrl;

    Get-SPEnterpriseSearchResultItemType -Owner $owner -SearchApplication $ssa | Where Name -eq "Microsoft Excel (Client)" | Remove-SPEnterpriseSearchResultItemType -Owner:$owner -SearchApplication $ssa -Confirm:$false
    $rit = New-SPEnterpriseSearchResultItemType -Name "Microsoft Excel (Client)" -Owner $owner -SearchApplication $ssa -Rules $rules -DisplayProperties $dispProps -DisplayTemplateUrl $sptemplateUrl
    
    Write-Host " > Search Result Type Created."
    
    return $rit;
}

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

$cd = gl
$fileNames = @("Item_Excel_Client.js", "Item_Excel_Client.html");

Get-SPWebApplication "http://mywebapp" | Get-SPSite -Limit ALL | ForEach {
    $spsite = $_;
    $spweb = $spsite.RootWeb;

    Write-Host $spsite.Url

    # Upload File(s)
    $fileNames | foreach {
        $fileName = $_;
        $fileContents = [System.IO.File]::ReadAllBytes("$cd\$fileName");
        $spfile = DropFile $spweb $filename $fileContents;
    }

    # Register Search Result Type
    $fileUrl = $spfile.Url.Replace(".html", ".js");
    CreateSearchResultType $spweb $fileUrl;
}

Better solution

Recently I stumbled upon the “Preferences” link at the bottom of the search result page. This allows each user to control how links in the search results should be opened.

Search preferences

 

This actually changes the experience for the given user immediately… awesome! I did some digging and it seems to be saved globally to the Search Service Application (Proxy), so all Web Applications and Site Collections making use of the same SSA should give the user a uniform experience.

The question still stands whether this setting can be pushed out programmatically to a specific user or group of users. I was thinking along the lines of the following script, but no luck so far.

$web = Get-SPWeb http://intranet
$ctx = [Microsoft.SharePoint.SPContext]::GetContext($web)
$pref =[Microsoft.Office.Server.Search.Administration.UserPreference]::GetUserPreference($false, $ctx)
$pref

HTH


SharePoint and PowerShell remoting


February 28, 2014 - 13:30, by Steven Van de Craen - 2 Comments

In my current project I’m dabbling with PowerShell to query different servers and information from different SharePoint 2010 farms in the organization. This blog contains a brief overview of the steps I took in order to get a working configuration.

Enable remoting and credential pass-through

You need to enable remoting and also credential pass-through. The latter is important because your SharePoint statements will need to authenticate to the SQL Server containing your SharePoint databases, or all your statements will fail with an access denied.

Enable-PSRemoting

I did this on both the “client” and the “server”, because my client can actually be queried itself as well…

Enable-WSManCredSSP -Role Client –DelegateComputer MYSERVER01

I ran this on the “client”.

Enable-WSManCredSSP –Role Server

I ran this on the “server”.

CredSSP allows the credentials to pass-through (double hop) . There’s a security note in the TechNet article;

Caution: CredSSP authentication delegates the user's credentials from the local computer to a remote computer. This practice increases the security risk of the remote operation. If the remote computer is compromised, when credentials are passed to it, the credentials can be used to control the network session.

» Enable-PSRemoting: http://technet.microsoft.com/en-us/library/hh849694.aspx

» Enable-WSManCredSSP: http://technet.microsoft.com/en-us/library/hh849872.aspx

Force PSVersion 2.0

If you have multiple versions of PowerShell then most likely new instances will be using the latest version. There is a common issue regarding SharePoint 2010 Management Shell and PowerShell 3.0 (or above) outlined here: http://support.microsoft.com/kb/2796733.

Microsoft SharePoint is not supported with version 4.0.30319.17929 of the Microsoft .Net Runtime.

If you’re seeing this issue when remoting you can create a new PSSessionConfiguration on the “server” and have “clients” reference it.

Register-PSSessionConfiguration -Name PS2 -PSVersion 2.0

I ran this on the “server” in a PowerShell 3.0 prompt.

» Register-PSSessionConfiguration: http://technet.microsoft.com/en-us/library/hh847899.aspx

Invoke-Command / Enter-PSSession

There’s but one thing that remains, and that is to see if it worked. Make sure to specify CredSSP and the reference to the PSSessionConfiguration object.

Invoke-Command -ComputerName MYSERVER01 -ConfigurationName PS2 -Authentication CredSSP –Credential MYDOMAIN\myuser -ScriptBlock { asnp Microsoft.SharePoint.PowerShell; Get-SPFarm }

» Invoke-Command: http://technet.microsoft.com/en-us/library/hh849719.aspx

» Enter-PSSession: http://technet.microsoft.com/en-us/library/hh849707.aspx

 

Happy remoting!


Excel REST API not refreshing data


February 20, 2014 - 07:00, by Steven Van de Craen - 0 Comments

We’re using the Excel REST API in SharePoint 2010 to visualize some graphs directly on a web page. The information is stored in an Excel workbook in a document library and that had connections to backend data stores. The connection settings inside the workbook were configured with credentials inside the connection string. However we noticed that the graphs on the web page would not update unless we opened and saved the workbook.

Trusted File Locations

There’s a setting in your Trusted File Locations (in the configuration of the Excel Service Application) that you have to check, in order to have the REST API update the connections.

Allow External Data Using REST 

Unattended Service Account

Even if you have credentials inside the connection string, you’ll still need to configure an Unattended Service Account because the ECS engine will impersonate that user to “open” the workbook.

This is quite accurately logged in the ULS logs, but somehow we missed it at first:

02/10/2014 10:50:59.25  w3wp.exe (0x2268)        0x0540  Excel Services Application            Excel Calculation Services             c35r                Medium               CredentialsProvider.GetCredentials: the following exception occurred when trying to acquire the unattended account credentials: Microsoft.Office.Excel.Server.CalculationServer.Interop.ConnectionException: Exception of type 'Microsoft.Office.Excel.Server.CalculationServer.Interop.ConnectionException' was thrown.     at Microsoft.Office.Excel.Server.CalculationServer.SecureStoreHelper.GetSecureStoreCredentials(Request request, String secureStoreApplicationId, Boolean delegateUser)     at Microsoft.Office.Excel.Server.CalculationServer.UnattendedAccount.GetCredentialsFromStore(Request request)     at Microsoft.Office.Excel.Server.CalculationServer.UnattendedAccount.GetCredentials(Request request)     at Microsoft.Office.Excel.Server.CalculationServer.CredentialsProvider.GetCredentials(Request request, ConnectionInfo connInfo, String dataConnectionName, Credentials& credentials)            38a5d8ad-09a0-45eb-af89-ebf908bee2fc

02/10/2014 10:50:59.25  w3wp.exe (0x2268)        0x0540  Excel Services Application            External Data     3237       Information                Unable to establish connection using only the connection string. If a username and password are saved in the connection string, they may not be correct, or the Unattended Service Account may not be configured. [Session: 1.V23.619PvoW1uPgVeMNVtZtgxpi90.5.en-US5.en-US73.-0060#0000-10-00-05T03:00:00:0000#+0000#0000-03-00-05T02:00:00:0000#-006036.227417de-0d92-42c3-ad24-3f32334d87e21.N User: 0#.w|domain\user1]         38a5d8ad-09a0-45eb-af89-ebf908bee2fc

Configuring an Unattended Service Account is a matter of setting up a Secure Store Service Application and Target Application, and then configure the Excel Service Application to use that Application ID for Unattended Service Account.

Secure Store Service Application

Excel Unattended Service Account

Now we finally have up-to-date graphs on our web page without opening and saving the workbook.


Nintex Workflow and emailing to groups


February 19, 2014 - 15:08, by Steven Van de Craen - 0 Comments

Nintex Workflow is able to send emails via the Send notification action.

Nintex Workflow - Send notification

A question often asked is if it can send emails to SharePoint groups or Active Directory groups. The answer is; Yes it can!

There are some things you need to know though…

Send to an Active Directory group

You can use AD security groups, but they must have a (dummy) email value configured or the workflow will fail on this.

The email will only be sent to the direct users in the AD group. Nested AD groups will be ignored.

Send to a SharePoint group

This works about the same as AD groups. The email will be sent to direct users in the SharePoint group, and to direct users of any nested AD group in the SharePoint group. It won’t go into nested AD groups of the AD group though (same as above).

Also, you cannot nest SharePoint groups.

 

HTH


Hyper-V and NAT


January 16, 2014 - 07:13, by Steven Van de Craen - 1 Comments

Networking “challenges”

I like Hyper-V. I really like it. But I’m not blind for shortcomings either. The biggest frustration for me has always been the lack of NAT. Up until now I was using ICS (Internet Connection Sharing) but this was far from perfect;

» It used the same IP address range as the Windows Phone “Internet Sharing” feature. So when I want to tether I had to disable ICS and thus lose connectivity inside my VMs. Really annoying when you need to have both.

» Sometimes I’m connected through an Ethernet cable, other times via WiFi. Having to switch the ICS to a different adapter requires quite some clicks. I semi-automated this with PowerShell, but it wasn’t perfect.

» You can’t establish a Cisco AnyConnect VPN connection when ICS is enabled. You can enable it after the connection is established, but still.

» ICS seems less loved in Windows 8 and Windows 8.1. I often had no connectivity until I disabled ICS on my adapters, even though I wasn’t actively using it at the time.

But if you want your VM to have internet connectivity without putting it directly on your network (avoid machine name conflicts, avoid people accidentally connecting to “your” VM instead of theirs, …) there’s little choice, until now.

A perfect match

Ironically, the solution lies with a competitive product; VMWare’s NAT Service. When you install VMWare’s virtualisation product (like Player), it installs a Windows service and creates a network adapter that has NAT capability. You can then connect your Hyper-V Virtual Switch to the VMnet8 adapter and you’re all done!

I accidentally stumbled upon this “solution” when it was mentioned by Thomas Vochten on Twitter.

He was kind enough to write it up into a blog post; http://thomasvochten.com/archive/2014/01/hyper-v-nat

It immediately solved all of my issues with ICS and took away my biggest frustration with Hyper-V Smile

Hope it helps you too!


SharePoint Foundation 2013 broken search experience


December 10, 2013 - 10:33, by Steven Van de Craen - 80 Comments

Issue

I recently examined a SharePoint Foundation 2013 environment where all Search Boxes had gone missing overnight. Also, when browsing to the Search Center I received an error. The ULS logs showed the following error:

System.InvalidProgramException: Common Language Runtime detected an invalid program.

at Microsoft.Office.Server.Search.WebControls.SearchCommon.GetUserAdvancedLanguageSettingsUrl()

at Microsoft.Office.Server.Search.WebControls.ScriptApplicationManager..ctor()

at Microsoft.Office.Server.Search.WebControls.ScriptApplicationManager.GetCurrent(Page page)

at Microsoft.Office.Server.Search.WebControls.SearchBoxScriptWebPart.OnInit(EventArgs e)

at System.Web.UI.Control.InitRecursive(Control namingContainer)

at System.Web.UI.Control.AddedControl(Control control, Int32 index)

at System.Web.UI.WebControls.WebParts.WebPartManager.WebPartManagerControlCollection.AddWebPartHelper(WebPart webPart)

at System.Web.UI.WebControls.WebParts.WebPartManager.WebPartManagerControlCollection.AddWebPart(WebPart webPart)

at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartWithRetry(WebPart webPart)

at Microsoft.SharePoint.WebPartPages.SPWebPartManager.CreateWebPartsFromRowSetData(Boolean onlyInitializeClosedWebParts)

at Microsoft.SharePoint.WebPartPages.SPWebPartManager.LoadWebParts()

at Microsoft.SharePoint.WebPartPages.SPWebPartManager.OnPageInitComplete(Object sender, EventArgs e)

at System.EventHandler.Invoke(Object sender, EventArgs e)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

KB2837628 and/or KB2850058

It took some investigating but we managed to track down the Windows Updates that seem to cause this issue: http://support.microsoft.com/kb/2837628 and http://support.microsoft.com/kb/2850058. Installing either on a SharePoint Foundation 2013 will break the search infrastructure. Note that these updates CANNOT be uninstalled.

Impact

Other users have also reported the exact same issue and cause on the MSDN forums, but no fix is currently available. The impacted environment had a localized (Dutch) version of SharePoint Foundation 2013 running, other cases also mostly talk about localized versions, so it might be that the English SKU is unaffected.

All versions (both English and localized) of SharePoint Foundation 2013 are impacted.

» http://social.msdn.microsoft.com/Forums/en-US/905c6aac-2ad9-4099-b4a1-d4cdd6ff4b23/kb-2837628-removes-search-box?forum=sharepointsearch

» http://social.msdn.microsoft.com/Forums/sharepoint/en-US/3b403821-42d2-4139-8afb-7c9312b57bd4/search-box-disappeared-foundation?forum=sharepointsearch

» http://blogs.technet.com/b/stefan_gossner/archive/2013/10/26/october-2013-cu-for-sharepoint-2013-has-been-released.aspx (Comments section)

» http://social.technet.microsoft.com/Forums/sharepoint/en-US/4714d906-5bbe-4eca-b666-b0e65367a0a3/update-kb2850058-breaks-search?forum=sharepointsearch

Reproduce

Initially I was unable to reproduce this issue as the aforementioned update wouldn’t install (“The expected version of the product was not found on this system”), but ultimately I did find how it probably ended up on impacted systems.

  1. Install SharePoint Foundation 2013
  2. Install SharePoint Server 2013 March Public Update
  3. Install KB2837628 and/or KB2850058

So basically if you run the Server PU (and maybe this applies to CU’s as well) on a Foundation it will update without issues, but then Windows Updates will start rolling out SharePoint Server 2013 updates. If this is an unsupported scenario they should have a blocking mechanism to avoid installing Server PU’s or CU’s onto a Foundation.

Solution: KB2760625

The October 2013 or December 2013 Cumulative Update do NOT fix this issue. For now avoid installing this update altogether. It isn’t supposed to wind up on Foundation installations.

I’m currently working together with Microsoft PSS to get to the bottom of this and -hopefully- a hotfix.

An hotfix has been released and confirmed to fix the issue: KB2760625 (http://support.microsoft.com/kb/2760625). After installation the Configuration Wizard needs to be run.

This hotfix should be incorporated into the April 2014 Cumulative Update, so once that is available there shouldn’t be a need to install this specific hotfix separately.

 

Update (12/12/2013)

There’s are reports that KB2850058 has the same impact, so be careful! but this appears to be false. This update is related to Outlook 2007 Junk Email Filter. I can now confirm this (17/12/2013).

» http://social.technet.microsoft.com/Forums/sharepoint/en-US/4714d906-5bbe-4eca-b666-b0e65367a0a3/update-kb2850058-breaks-search?forum=sharepointsearch

I have also logged this as a support case with Microsoft, let’s hope this can clear the mist. I’ll update my findings here and on the above forums.

Update (13/12/2013)

It appears that English installations of SharePoint Foundation 2013 are also impacted.

I’m still working with PSS to get this resolved.

I haven’t been able to reproduce the issue on my dev environment. I tried WS2012 and WS2008R2 but KB2837628 seems unwilling to install (“The expected version of the product was not found on the system.”). If anyone has reproducible steps please let me know.

Update (14/12/2013)

Managed to reproduce the issue. See above for the reproduce steps.

I verified KB2850058 on my installation. It wouldn’t install because I didn’t have Outlook 2007 on it, but it appears to be unrelated since it is an update for the Outlook 2007 Junk Email Filter. Most likely both updates were installed on the environment of the user that reported this. I had my numbers screwed up.

Update (16/12/2013)

I tried the recently released December 2013 Cumulative Update but no luck.

Microsoft PSS is still examining the issue. To be continued.

Update (17/12/2013)

After getting notified that KB2850058 was really also causing this issue, I retraced my steps and I had gotten the KB numbers wrong. So we have both KB2837628 and KB2850058 causing the same issues. Thanks Lee and Matt for informing me on this via the comments below!

Update (23/12/2013)

I don’t expect a solution to be provided in the next few weeks :(

Update (4/02/2014)

I finally have an update to share after weeks of back-and-forth emailing regarding the issue. I’m absolutely not happy with the answer and have expressed my sentiment accordingly. Still, I doubt that will make an impression on anyone. Here’s the update;

The Product Group is acknowledging the problem but declared that they can only fix it over the April 2014 CU as there will be no February 2014 CU.

This means for the affected customer that cannot wait until April need to reinstall SharePoint in order to address  the error in a supported manner. Some other customers tried to replace binaries with older versions, we haven’t yet received the feedback if this worked out for them – we are asked to discourage this kind of experiments anyway.

Update (5/02/2014)

A final word from the escalation engineer was that this is an acknowledged bug, but due to the release cycles of hotfixes and updates this issue cannot be fixed any sooner than the April 2014 Cumulative Update. Since this is well over two months away from now you’d be best in reinstalling your environment and avoid those specific Windows Updates, or live without Search until then.

Update (4/03/2014)

Service Pack 1 for SharePoint Foundation 2013 does not fix this issue. Furthermore, the KB for Service Pack 1 was amended with a notice to postpone installing SharePoint Foundation 2013 Service Pack 1.

Important A known issue in SharePoint Foundation 2013 SP1 can affect the functionality of the Search WebPart. We encourage you to limit production installations of SharePoint Foundation 2013 SP1 until a fix is available. SharePoint Server 2013 is not affected by this issue.

http://support.microsoft.com/kb/2850035

Update (20/03/2014)

A hotfix has finally been released: http://support.microsoft.com/kb/2760625! Make sure to run the Configuration Wizard afterwards.


SharePoint GroupBy ordering with calculated field


December 6, 2013 - 17:16, by Steven Van de Craen - 0 Comments

Something that almost every client asks me is how to change the display order of the GroupBy field in a SharePoint List. For instance, let’s say you have a grouping on a status field. Unfortunately the List Settings only allow you to sort them alphabetically, either ascending or descending.

GroupBy Status Unordered

In case of status it makes more sense to have it in a logical order. An easy option is to prefix the status with a number, but if the list is already in use you can’t simply change the existing status values since it might break things like workflows checking on them. Also if you want to insert an additional status value later on you’ll have a tough time renaming them.

A cleaner solution is to make use of a Calculated Column that prefixes the status with a number. This is a really flexible solution because you can easily update the calculation formula to reorder or change statuses.

How to?

First you’ll have to map your statuses to numbered statuses. Excel is a huge help in this because it uses the same calculation engine as calculated fields.

image

The first column are your original statuses, if you name it exactly as your own SharePoint status field, the formula will be 99% ready to be pasted into SharePoint.

The second column is -in this particular case- constructed using the following formula:

=CONCATENATE(IF([Service Status]="Draft";"01";IF([Service Status]="New Request";"02";IF([Service Status]="In Progress";"03";IF([Service Status]="Closed";"04";IF([Service Status]="Discontinued";"05")))));". ";[Service Status])

Finally we just have to replace all semicolons with colons and then paste it into a SharePoint Calculated column.

Field ItemStatus

All that remains is to update our views to use the Calculated Column for Grouping.

GroupBy Status Ordered

 

Quick win; we added an ordered status field that doesn’t interfere with any existing automations or input screens, without the need for heavy customizations.


Fixing a broken People Picker in Office 2010


November 27, 2013 - 20:41, by Steven Van de Craen - 0 Comments

Recently I was on a troubleshooting mission in a SharePoint 2010 / Office 2010 environment where the People Picker in the Document Information Panel of Word wasn’t resolving input, nor did the address book pop up after clicking it.

I fired up Fiddler to see a HTTP 500 System.ServiceModel.ServiceActivationException error on the /_vti_bin/spclaimproviderwebservice.svc when interacting with the People Picker.

Fiddler

Opening that WCF service address in a browser reveaed the actual issue.

This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item

A quick search showed this is because multiple host headers were configured on the IIS site (and also as Alternate Access Mapping). If you do this you’ll need to modify the web.config to allow multiple site bindings for WCF services.

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" >
    </serviceHostingEnvironment>
  </system.serviceModel>

Alternatively, this could also have been avoided by using Web Application Extends if you want multiple URLs for the same Web Application.

Hope this helps.


Retargeting SharePoint Lookup Fields


November 20, 2013 - 21:32, by Steven Van de Craen - 0 Comments

Recently I was in an upgrade project and, as any good upgrade project, there are some kinks that needed ironing out. The issue was a corrupted list that had to be recreated and repopulated. Now there’s a challenge in that itself, but it’s not the subject of this post. Let’s just say that we recreated the list identical as to how it was before and also managed to repopulate it with the same data as before (note: we made sure all content had the same ID value as before).

Complicating the matter were several lookup fields in other lists referencing our list. And after recreating the list its ID no longer corresponded to the one in those lookup fields.

 

Sorry, something went wrong The list you selected does not exist. It may have been deleted by another user. Create a new lookup field pointing to a list that does exist.

Sorry, something went wrong
The list you selected does not exist. It may have been deleted by another user. Create a new lookup field pointing to a list that does exist.

SPFieldLookup.LookupList

The Microsoft.SharePoint.SPFieldLookup class exposes a LookupList property with getter and setter, but the setter only works if the property hasn’t been set previously.

Reflection

There IS a private LookupListId property but we can only access it with some Reflection magic. I’m no stranger to using .NET Reflection but a general advice is to tread careful and all disclaimers apply. Luckily there’s another solution…

Door #3

So what’s behind Door #3? It’s the SPField.SchemaXml property! It exposes a setter which allows us to change quite a bit. Since I keep forgetting about this gem I hope that blogging about it will make me remember.

Here’s some info from the MSDN article:

Do not call the Update method when using the SchemaXml property to modify a field.

Using this property to set a read-only attribute, such as InternalName, generates an exception.

So with that it was really easy to write a script to fix it.

# Correct/new list ID
$newGuid = New-Object System.Guid("{80c851ba-887a-465d-9b09-c3084ced1b96}")

# Init
$web = get-spweb http://intranet/myweb
$list = $web.Lists["My List"]
$field = $list.Fields["MyLookup"]

# Debug output
$field.SchemaXml
<Field Type="Lookup" DisplayName="MyLookup" Required="FALSE" EnforceUniqueValue
s="FALSE" List="{5b8c5349-06be-436f-a0c7-b5451cabcee7}" ShowField="LinkTitleNoM
enu" UnlimitedLengthInDocumentLibrary="FALSE" RelationshipDeleteBehavior="None"
 ID="{1ea44ae5-b618-47b3-b475-93b9fba1daa3}" SourceID="{60322c84-4db5-45a5-85cc
-a883a4a980eb}" StaticName="MyLookup" Name="MyLookup" ColName="int1" RowOrdinal
="0"/>

# PowerShell Xml magic to change the List attribute value
$fieldXml = [xml]$field.SchemaXml
$fieldXml.Field.List = $newGuid.ToString("B")
$field.SchemaXml = $fieldXml.OuterXml

# Debug output
$field.SchemaXml
<Field Type="Lookup" DisplayName="MyLookup" Required="FALSE" EnforceUniqueValue
s="FALSE" List="{80c851ba-887a-465d-9b09-c3084ced1b96}" ShowField="LinkTitleNoM
enu" UnlimitedLengthInDocumentLibrary="FALSE" RelationshipDeleteBehavior="None"
 ID="{1ea44ae5-b618-47b3-b475-93b9fba1daa3}" SourceID="{60322c84-4db5-45a5-85cc
-a883a4a980eb}" StaticName="MyLookup" Name="MyLookup" ColName="int1" RowOrdinal
="0"/>

Happy days!


Corrupt system Content Types


November 7, 2013 - 19:22, by Steven Van de Craen - 0 Comments

I was at a client recently that couldn’t access ANY of their document libraries anymore. New libraries were also affected by this.

The SharePoint ULS logs kept spawning the following error:

10/18/2013 14:11:10.08 w3wp.exe (0x128C) 0x1878 SharePoint Foundation Runtime tkau Unexpected System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.SharePoint.WebPartPages.ListViewWebPart.PrepareContentTypeFilter(SPList list, Hashtable[] excludedTransformers) at Microsoft.SharePoint.WebPartPages.ListViewWebPart.GenerateDocConvScriptBlock(SPWeb web, SPList list) at Microsoft.SharePoint.WebPartPages.XsltListViewWebPart.OnPreRender(EventArgs e) at Microsoft.SharePoint.WebPartPages.WebPartMobileAdapter.OnPreRender(EventArgs e) at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 1267cf7d-19e3-4687-a4f3-d4ca48af847c

Digging deeper you can still access List Settings via the following page: http://yoursite/_layouts/mcontent.aspx. Since it seems related to the Content Types I inspected these first. As you can see the Parent Content Type was blank!

Content Type Information

 

Turned out that all of SharePoint’s out of the box “system” Content Types (Item, Document, Folder, …) were missing in the Site Content Type overview.

Final proof was delivered by trying to visit the Content Type Settings of one of these “system” content types: http://yoursite/_layouts/ManageContentType.aspx?ctype=0x0101. This threw an unexpected error.

Solution

These Content Types are made available through a Site Collection Feature called “ctypes”. By reactivating this feature everything was gold again.

Disable-SPFeature -ID 695B6570-A48B-4A8E-8EA5-26EA7 FC1D162 -Url http://yoursite -Confirm:$false
Enable-SPFeature -ID 695B6570-A48B-4A8E-8EA5-26EA7 FC1D162 -Url http://yoursite 


 Next >>