Page mode and JavaScript

So I ran into a scenario recently where a customer had a jQuery script making some DOM modification which they wanted and everything looked good.

Until you went to edit the properties of some web parts. Unfortunately due to the DOM manipulation that the script was doing it was impossible for a user to edit these web parts.Not all that helpful.

Given that this is on a custom page layout the answer is just to add a EditModePanel with the attribute PageDisplayMode=”Display” surrounding the offending script tag, job done, the script is no longer in the page in design, AKA edit, mode.

But what about when the script still needs to do some changes or is being injected via a script editor web part?

The solution is luckily very simple. SharePoint kindly puts a hidden input field into the page while it’s in design mode.

<input name="MSOLayout_InDesignMode" id="MSOLayout_InDesignMode" type="hidden" value="1"/>

All you need to do is check this with a single line of jQuery and use this to control your logic flow.

if($('#MSOLayout_InDesignMode').val() !== “1”){
    //do display mode only stufff
}

Nice and easy, two simple methods of having scripts which only run in the display mode of your choosing.

Posted in Uncategorized | Leave a comment

SharePoint MVPs do an AMA

Are you a redditor?

If you are start collating some questions for the SharePoint MVP AMA which will be held on October 30 6am (October 29 at 1pm EST according to the post in /r/sharepoint). If you’re not a redditor then just come along and lurk.

There will be a lot of well known SharePoint and Office 365 MVPs participating so this is a great time to ask those burning questions.

See you there :)

Posted in Uncategorized | Leave a comment

Why do I need to use SPWeb.AllowUnsafeUpdates?

We have a customer who has a couple of custom feature bound onto a WebTemplate that was giving them grief when they attempted to provision sites from this template via PowerShell but worked just fine when using the web UI.

What the team was experiencing was that during the activation of certain features errors with the message “The security validation for this page is invalid”. Now the fix is simple, set AllowUnsafeUpdates=true during the custom feature activated code.

But why do we need to do this?

First let’s look at what’s happening in the context of making these changes via the web UI. In SharePoint there is a FormDigest control, this control places some security validation information into the page which is included in the POST back to the server. SharePoint uses this information to verify that this request to change the contents of its databases does correspond to a request from a page that was served up by SharePoint.

Now when we attempt to make these changes from custom code that’s getting executed from PowerShell there’s no page, no POST and no form digest information bundled along. So SharePoint attempts to verify the form digest a.k.a “security validation” and in the interests of self protection quite rightly throws an exception. This behaviour of SharePoint wanting it’s changes to come from a web browser can also present via the message “Updates are currently disallowed for GET requests”.

Of course because what we’re trying to do here is a valid use case SharePoint supports disabling these checks via the AllowUnsafeUpdates property on the SPWeb object. Now because setting this property to true opens up potential security risks you shouldn’t just set it to true and leave it that way, just toggle it for while you need to make these changes and flip it back to the way it was.

bool unsafeUpdates = web.AllowUnsafeUpdates;
web.AllowUnsafeUpdates = true;
//make some changes;
web.AllowUnsafeUpdates = unsafeUpdates;

Hopefully this has helped to explain the WHY behind the use of AllowUnsafeUpdates that you’ll often see in custom server side code.

Posted in Uncategorized | Leave a comment

SharePoint 2013 Search: Add User Profile Properties to the Full Text Index

We would like to allow users to search on values stored against user profiles without needing to use an explicit managed property search, i.e. they just want to type in the keyword and have the relevant people returned. Pretty much the problem as stated in this SharePoint.StackExchange post.

Matthew McDermott’s great blog post provides an approach to this problem for SharePoint 2010, http://www.ableblue.com/blog/archive/2011/03/15/sharepoint-people-search-and-alias-fields/. I’d encourage you to read that, don’t worry, this post will wait for you.

OK, make sense? Just set the ‘Alias’ flag against the User Profile Property, create a new Managed Property and map into RankingWeightName and you’re done once a full crawl is completed.

However the fix that Matthew proposes treats the new property as an analog of the name field, thus documents can appear to be authored by entries in this field. Sure for some scenarios this is exactly what you want, but it might not be, in my case this is a behaviour I want to avoid.

image

I want to add something that is a match across a number of people in your environment, say Office Location, Business Division, Job Title or any other property which shouldn’t really be an alias.

So, how do I get the behaviour I want?

There is now some additional settings against the managed properties in SharePoint 2013 which allows you to associate the managed property with a specific full text index! Turns out that a simple change to these settings is all I need to achieve my desired outcome.

Locate the managed property that you want to search within in your search service application and edit it. Scroll down and locate the Searchable checkbox. Now to my thinking all you should have to do is check this box and you’re good, the guide text even makes it look like this is the case by referring to a metadata field which is relevant to people. This isn’t the case, as this is a property related to people you need to do a bit more.

Check the Searchable box and click on the Advanced Searchable Settings button.

image 

This launches a dialog, now simply switch the Full-text index drop-down to use the PeopleIdx:

image

Remember to  click OK in both the dialog and edit page to save your changes, jump over to the content source which contains your people source and run a full crawl. The content source you’re after will contain a start address which uses the sps3 or sps3s protocol if you’re not sure which one it is.

Once this is done crawling you should now be able to search for people using category searches and not needing to specify the managed property you’re searching within.

Posted in Search, SharePoint, Uncategorized | 7 Comments

MVPComCamp: PowerShell Automation for Everyone

Last weekend around the world there was a global series of events hosted by Microsoft known as MVPComCamp. I was one of the people to present here in Auckland, New Zealand. I was speaking on a topic dear to me, automation. I’m basically a guy who hates to do boring, repetitive tasks so I like to script as many things as I can.
The aim of my presentation was to show how easy it is to write PowerShell and give everyone the tools that they need to start doing so.

Posted in Conferences, Configuration, Deployment, Development, PowerShell | Leave a comment

Extracting a full list of users from SharePoint

I had an interesting ask from a customer the other day.
“Can I get a report of all the users in the system along with some key pieces of data that is stored on their user profile?”
Sure there are probably a bunch of other ways to do this, search springs to mind. But for this customer the best thing I could give them was a csv file so they could generate some reports and charts from this information. So once again it’s PowerShell to the rescue.

A few things to note about this script, first and foremost the user account executing it MUST have rights to connect to the User Profile Service Application. If they don’t you get a lovely error message which doesn’t make a lot of sense:

New-Object : Exception calling ".ctor" with "1" argument(s): "Object reference not set to an instance of an object."
 + $upa = new-object <<<<  ("Microsoft.Office.Server.UserProfiles.UserProfileManager") $context 
 + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
 + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

If you do have to grant your account permissions to the User Profile Service Application it is necessary to A) restart the service on the server and B) get a fresh PowerShell instance in order for this change to get picked up.This version gets every user profile in your UPA, if you’re after certain people either use .Search() or do some filtering inside the enumeration loop.

Add-PSSnapIn Microsoft.Sharepoint.Powershell
$site = Get-SPSite "http://mysiteurl"
$context = Get-SPServiceContext $site
$upa = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$enumer = $upa.GetEnumerator()
$enumer.Reset()
while($enumer.MoveNext()){
     $user = $enumer.Current
     $row = $user.RecordId.ToString() + ", " + $user.AccountName  + ", " + $user.DisplayName+ ", " + $user["PropertyOfInterest1"]
     write-output $row
}

According to the docs for IEnumerator on MSDN MoveNext() will return false when it moves beoynd the bounds of the collection being enumerated and Reset() followed by MoveNext() should be used to set the Current item to the first item in the collection.I’ve used Write-Output in this case because I can easily combine this with Output-File to create csv output files like so:

.\ReadUsers.ps1 | Output-File .\UserDump.csv
Posted in PowerShell, SharePoint | Tagged , , | Leave a comment

The Sandbox is dead! Long live the Sandbox!

So, you may have heard that Sandboxed solutions have be deprecated in SharePoint 2013. This was one of the big news items that came with the new version of the product along with the new SharePoint App Model.

That’s not entirely correct.

User code is deprecated. What does that mean for us as developers?

Simply that we can safely continue to use sandboxed solutions to deliver declarative customisations to our SharePoint site collections. Things like Web Templates, Content Types, Custom List definitions etc., are all still supported and will still be so for vNext.

I’m really happy that this clarification has been made, and confirmed by another source inside Microsoft. This makes the future of delivering customisations to SharePoint Online and at a Site Collection level much clearer.

Posted in Uncategorized | Leave a comment