Radu Tut did a wonderful blog about how to get Search Analytics Reports programmatically in SharePoint 2013. I am quite grateful for his guidance and it’s undoubtedly the most referenced article on the topic (even being referenced in Microsoft blogs and other documentation).

I followed Radu’s guidance and have successfully retrieved usage data from my site collections in 2013, but I’ve discovered a few things I’ve not seen anyone talking about:

  1. It is important to note that the DateTime value you use should be UTC. If not, you will, at some time during the day–depending on your offset–get a “Specified argument was out of the range of valid values” error when trying to get the furthest back data (example: -14 days for Day) if you use Local time. Internally, SharePoint uses DateTime.UtcNow.Date (see reflection of Microsoft.Office.Server.Search.Analytics.AnalyticsItemData in the Microsoft.Office.Server.Search.Applications.dll).
  2. To my surprise, I was able to retrieve usage data from a 2010 site collection in SP2013! Apparently, SharePoint is tracking and compiling this data, but the 2010 UI has no way to interface with the data. Thus, if you need usage data for a 2010 UI site collection in SharePoint 2013, turn to your Devs or PowerShell-savvy Admins: If your site is being crawled, the 2013 usage data you seek is in there!
  3. The time period for SP2013 to compile usage data is fairly lengthy (at least 15 minutes in my tiny dev farm). If you attempt to retrieve the data while SharePoint is compiling it, you’ll get back a big fat ‘0’. For expected results, make sure you’re not retrieving the data while SharePoint is compiling it. 🙂 I believe this compilation is done by a timer job once a day at midnight, by default (I was up pretty late working on my project when I discovered this behavior).

Happy reporting!


New Job

I am happy to announce that I started a new job as a SharePoint Developer at The Church of Jesus Christ of Latter-days Saints on Monday, March 10. It’s been a bit of a slow start since I broke my arm Saturday while skiing (thanks, Olympics, for giving me the courage to try something stupid) and had to have it surgically put back together this week. Been getting to know some of the great people who make up the SharePoint Team and am thrilled to be working with them.

Another day, another discovery on my quest to migrate our farm from SharePoint 2010 to SharePoint 2013. I started noticing image quality problems with the user thumbnail images in my upgraded farm: The small and large thumbnail images were looking very blurry. This was particularly evident when I viewed my My Site Host’s People page (MyPeople.aspx). The photo of myself on the left side was fairly blurry, but the small photos of the people I am following were nearly indistinguishable. Okay, what’s going on here?

Well, it turns out that Microsoft has changed the default thumbnail sizes for User Profile photos in SharePoint 2013. Here’s a comparison of the maximum dimensions (pixels) as given in Microsoft.Office.Server.UserProfiles.UserProfilePhotos:

Max pixels
Thumbnail SP2010 SP2013
Large 144 300
Medium 96 72
Small 32 48

As you can see, the dimensions for the large and small images have increased but has decreased for the medium image.

The new dimensions for the medium and small images isn’t much of a problem thanks to the handy dandy PowerShell cmdlet Update-SPProfilePhotoStore (read more at TechNet). The detailed description given in the TechNet reference still refers to 2007, but what this cmdlet does still apply to upgrades from 2010. By executing Update-SPProfilePhotoStore -MySiteHostCollection http://sppaule/my my thumbnail images were regenerated to match the default sizes desired by the system.

There’s still one gliche: SharePoint’s thumbnail image creation routine (found in Microsoft.Office.Server.UserProfiles.UserProfilePhotos) won’t enlarge images. (I’ve got a background in design and photography and can say with assurity that this is a good thing!) This means the large thumbnails stay at a maximum 144 pixels. Since they are displayed at 200 pixels, the image is thus enlarged by the browser by 38% causing bluriness. Unfortunately, unless you have a repository of higher resolution images of your users, you’re stuck.

This is where I think the new Image Renditions can come in quite handy. For more information about Image Renditions, I highly recommend MVP Waldek Mastykarz’s wonderful post “Image Renditions in SharePoint 2013.” If the User Profile Photos were to use Image Renditions, your originally uploaded file could be stored for use whenever the preset thumbnail sizes were inadequate. This would allow for a regeneration of the large thumbnail image should it’s default size increase again in the future. Not only that, but uploading a file could conceivably trigger a scaling-and-cropping UI similar to that used by Image Renditions (hopefully a little simpler) wherein the user uploading the photo could scale and crop the original photo right in the browser!

For SP2010, I gave our HR department a webpart which did allow them to scale and crop the original right in the browser (using Jcrop) and stored the original photo in another photo library. Now I’m just kicking myself for not storing the cropping information as properties/fields along with the original photo. Had I done so, I’d be able to programmatically regenerate the large thumbnail images at the new SharePoint 2013 largeThumbnailSize of 300 pixels and perhaps even implement something using Image Renditions. (Fortunately, my webpart actually saves the cropped image at full resolution. So, I only need to rescale the images programmatically in order to generate new large thumbnails for SharePoint 2013. Phew!)

One final note: Update-SPProfilePhotoStore has one other side benefit for which I’d like to give my gratitude to the Microsoft team who put it together! In our migration to SharePoint 2013, we are changing our web application’s default zone to a different domain name and moving the My Site Host under this web application (lots of work and not particularly recommended to have the My Site Host under the same web application, but it’s going to save our users–and thus me–a lot of headache). Thus, when the User Profile Service was upgraded from SharePoint 2010 to SharePoint 2013, all of the user’s profile photos were still pointing to the old domain name. Fortunately, the old farm was still running and accessible under the old domain name. Having not migrated the My Sites Host content (I wanted to start clean with a 2013 My Sites Host), I didn’t have the user photos in the new SP2013 farm. I ended up writing a console application which would copy the user photos I needed from the old farm to the new farm (hence my last post). Turns out, that wasn’t necessary. To my surprise–and the credit of the Microsoft team–Update-SPProfilePhotoStore retrieved the photo from the old farm using the URLs in the new farm’s user profiles, resized them (except for the large thumbnail as spoken of above), stored the sizes (144, 72, and 48) in the new farm, and updated the URL in the user profile to point to the new 2013 My Sites Host > User Photos > Profile Photos. SLICK!

So, despite the shift in default image sizes for User Photo thumbnails, there is a convenient way to update your thumbnails. If Microsoft were to integrate Image Renditions with the User Photos, the whole process will become much more robust for all SharePoint consumers. I’m crossing my fingers!


Sometimes, the old ways just work cleaner. After struggling for far longer than I should have to get files to post to my document library using the REST interface, I turned back the clock and looked at how I had done it in times past:

private static void PostFile(string url, byte[] bytes)
  HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
  r.Credentials = CredentialCache.DefaultNetworkCredentials;
  r.Method = "PUT";
  byte[] buffer = new byte[1024];
  using (Stream stream = r.GetRequestStream())
    using (MemoryStream ms = new MemoryStream(bytes))
      for (int i = ms.Read(buffer, 0, buffer.Length); i > 0; i = ms.Read(buffer, 0, buffer.Length))
        stream.Write(buffer, 0, i);
  WebResponse resp = r.GetResponse();

The url parameter that you pass to this method is simply the URL the document will have after being posted. Example: http://sppaule/sites/test/Shared%20Documents/TestFolder/test.txt (this example would put the file “test.txt” in the TestFolder folder of the Shared Documents library in the “test” site). The bytes parameter contains the byte[] of the file to upload.

“More isn’t always better, Linus. Sometimes it’s just more.” (Anyone name that movie?)


Warning: Fluffy explanation content ahead! If you want to skip the background info and get straight to the meat of this post, skip the next few paragraphs.

I would like to start this post by giving credit where credit is due. A few years ago, Mark Wilson wrote a blog post on how to use calculated fields to control the coloring of calendar items in the calendar view with some custom JavaScript (see SharePoint 2010 Colour Calendar post SP1 update). Without thinking too terribly much about how it was put together or worked, I put it into play with a solution that used event receivers to update a Single Line Text field to the values needed for Mark’s script (a Calculated field was too simple to meet the full business requirements). Worked beautifully!

Upon testing the solution in SharePoint 2013, I found it didn’t work. And, not just a little: Badly! No calendar events would show on the calendar and the ribbon would get stuck in “Loading…” So, I returned to Mark’s blog and was happy to find his update, SharePoint 2013 Colour Calendar. Reading through the comments, I was surprised to see a stream of people mentioning Mark’s script wasn’t working shortly followed by Mark’s “I fixed it” reply. Something was wrong here that needed a deeper look.

Turns out, Mark has been copying the code from Microsoft’s scripts and appending a line to execute his ColourCalendar function. That works just fine until Microsoft modifies their scripts–which is precisely what has been happening frequently in SharePoint Online (o365). Even his 2010 version of the scripts had to handle the pre- and post-SP1 releases differently. (No fault of Mark. The changes were just too drastic.) I, for one, wasn’t interested in getting into a “test and modify” loop every time I needed to deploy a Cumulative Update. Not only that, but the scripts Mark provides are UI specific. I wanted–and pretty much needed (see my last post)–one script that could handle the different UIs by itself and not be subject to continual necessary updates because of changes made by Microsoft.

There were two key elements to meeting my requirements to handle the UI versions and cumulative updates without troubles:

  1. _spPageContextInfo.webUIVersion: This allows us to test which UIVersion is being used by the page. Important when you consider that the DOM changes quite considerably with each UI version.
  2. Extending JavaScript functions without overwriting them: This allows us to insert our own function call without needing to copy the original function’s code. (My thanks to “xdazz” for the answer to this one on Stack Overflow.)

Integrating all of this together with the Module Pattern best practice gained from Scot Hillier’s SPC2012 session, “A Primer in HTML5 and JavaScript,” I came up with a new script that can be used in UI version 4 or 15 in SharePoint 2013.

Script source: DynamicCalendarColor.docx

To use the script source, download it and save the contents as text-only as ‘DynamicCalendarColor.js’ (you can use a different name, but be sure to modify the last line accordingly). From there, follow Mark’s rather well written instructions on SharePoint 2013 Colour Calendar. Be sure your page also loads the jQuery libraries! (I don’t include that in my script because jQuery is often used in many other solutions, as well. Don’t want to be loading it twice.)

There you go: You’re now a SharePoint Calendar Artiste!

This past week, I’ve been updating a custom solution to work in SharePoint 2013. Part of the feature modifies the out-of-box user interface using JavaScript. Only problem was: I needed different JavaScript for the different UI versions.

At first, I figured there should be some way to test the UIversion in the script and branch accrodingly, but I couldn’t find the UI version there.

So, I turned to the SharePoint:UIVersionedContent tag to control which JS file would load (one file for UI version 4 [SP2010] and one for UI version 15 [SP2013]). Unfortunately–as of the SP2013 March 2013 CU–the internal static method used to compare the versions (Microsoft.SharePoint.Utilities.SPUtility.UIVersionsAreCompatible(int, string), Microsoft.SharePoint, Version= will only accept version 3 or 4. Any other version numbers passed in throws an SPException with “Invalid UI string.” That knocked out most version control functions made available by Microsoft.SharePoint.dll (also affects ScriptLink.Register).

Finally, I found a workaround which turned out to be a better solution, overall (I’ll blog about that next).

It wasn’t until I was wrapping up a loose end on the new-and-improved solution that I was reviewing Scot Hillier’s SPC2012 session, “A Primer in HTML5 and JavaScript.” Within that session, Scot spoke of a little-used gem in the SharePoint JavaScript world: _spPageContextInfo. One of the variables available on _spPageContextInfo is webUIVersion. Bingo! But too late. Na ja!

In conclusion, if you need to know the UIVersion in JavaScript used for a SharePoint page, simply call: