Tuesday, June 2, 2020

One year anniversary as a blue badge at Microsoft


One year ago I joined the Microsoft Search Experiences team in Oslo as a program manager, and time has gone by really FAST (pun intended). Overall it has been an awesome experience - largely due to the great team I’m part of. It has been very different from my previous job as a consultant, thus hard to compare, but I’m not done yet and have things I want to accomplish while I’m still young.

Here’s a list of some of what I’ve been part of or accomplished over the past year – all non-NDA stuff :)

  • I’ve written way fewer blog posts compared to the last years, which was expected, but I do hope to get the volume up a bit again.
  • Released my Troubleshooting Search in SharePoint Online self-help manual on Amazon
  • Two trips to India
  • Two trips to the US
  • Three trips to Tromsø (northern Norway)
  • Written about 4,000 e-mails – yeah, I know that’s not much at all, but it is for me
  • Presented at Ignite and SPSOslo (about what I usually do)
  • Made a lot of contacts across the v-team which Microsoft Search is across
  • Organized a hands & crafts x-mas social workshop for my team
  • Worked on multiple features underway – from small to large
  • Got the Microsoft Search code base up and running and did multiple pull requests as part of a hackathon week, fixing some real but minor issues
  • Won the business value award at an internal hackathon with my fellow hackers
  • Worked to align the out of the box Microsoft Search offering and messaging with the PnP Modern Search web parts
  • Talked to a good amount of high value customers on various search topics – which is not that different from talking to smaller customers as the search issues and needs are not that different except scale ;)
  • Still trying to see if we can expose the Live Persona Card in Office 365 as a re-usable control in SPFx (not given up yet)
  • …and more

I’ve interacted and contributed on too many projects to count, and it has proved valuable to bring my SharePoint and Office 365 experience into the team. As Microsoft Search is expanding, SharePoint is still a large part of it content wise and knowing the inner workings when moving from classic to modern is never a bad idea.

Thursday, April 30, 2020

Governance tip on finding overshared content in O365/SharePoint


Unless you have put in place the right governance measures you might at some point experience content showing up in search which shouldn't be there. A common problem are items overshared to the Everyone except external users group. Using search itself, you can easily find these items and put in place the right measures to remedy any oversharing.

When someone creates a sharing link on a document in SharePoint Online today, the sharing information is stored in a searchable managed property in the search index named SharedWithUsersOWSUSER. The same information is stored in the internal SharePoint item field named SharedWithUsers.

By issuing the query below as any user (as it’s explicitly shared with everyone and everyone has access) you can find all documents with an everyone sharing link attached to them.


The same approach can be used with any claim/user/group as documented in the official eDiscovery documentation.

You can also try the below query to find items which are shared:

ViewableByExternalUsers:1 OR ViewableByAnonymousUsers:1

If you get the refiner values from SPSiteURL, you can aggregate all sites which have shared content.

If you want to remedy oversharing to everyone, you can turn off the showing the Everyone claim with SharePoint Online PowerShell:

Set-SPOTenant -ShowEveryoneExceptExternalUsersClaim $false

or with PnP PowerShell:

Set-PnPTenant -ShowEveryoneExceptExternalUsersClaim $false

This merely hides the claim from showing, so you might still want to run scheduled reports to find items which are shared with everyone in case you want to prevent this behavior.

Happy sharing!

Image by Markus Winkler @ Unsplash

Thursday, March 26, 2020

Searching within Office 365 Groups or Teams content


There are at least three ways to limit the search results within a group or a team using the keyword query language (KQL). These are cases where the managed property used exists on all items for the site/group.


If you know the URL of the groups site you can use a path filter, and remember the trailing slash (/) to avoid edge case inclusion of other data.


Site Id

If you know the underlying site id of the Groups site.


Group Id

If you know the Group Id, meaning the AAD id of the group, you can use this as well.


Bonus: Search within all the groups a user is member of

And here’s the kicker to effectively scope results to all the groups a user is member of. Say you have pulled out a list of all the groups a user is member of via the Microsoft Graph API:

?$filter=groupTypes/any(a:a eq 'unified')

Armed with all the group ids, you can issue a SharePoint Search REST query using a wildcard (*) as the query text and the following FQL in the refinementfilters property.



If you are a member of many groups, then I suggest using a POST payload instead of GET, and refinementfilters is not limited by 4k either (at the time of this writing) :)

See https://www.techmikael.com/2013/07/limiting-search-results-by-exact-time.html for an explanation of refinement filter usage.

Note: How the above syntax will work using the Microsoft Graph Search API which is in beta, is not known at this point.

Photo by Mike Szczepanski @Unsplash

Friday, March 20, 2020

I finally found a use case for the Surface Pen (after 4 years)

I’ve been using Surface Pro’s since the Pro 3 and I know have a Pro 6. I have always liked the form factor of it and each one of them came with a Surface pen. Sure, I’ve tested the pen for fun and used it occasionally to sign something, but in the end I’m a laptop guy, not a tablet guy when it comes to work. So the pens have trustfully followed along in my back back never being used.

Until now that is!

In my home office I have opted to get a speaker phone as wearing a headset for longer periods of time is uncomfortable. The advantage with cabled headsets is that they have a mute/unmute button on the cord, allowing you to sit back and toggle the microphone on and off based on the conversation.

With a speaker phone I can still mute and unmute. Doing so requires me to stretch over to the speaker, not having the button easily in my hand. When using Microsoft Teams, I can use a keyboard shortcut shift-alt-m, but that requires the application to be active and is a bit too quirky.

You probably see where this is going :)

The solution is pretty simple. Being a programmer I browsed around and found out how to programmatically toggle a microphone on/off. You can find the C# code over at https://github.com/wobba/MuteToggleMicrophone. (I did look at NIRCMD, but it mutes speaker as well as mic when devices have the same names.)

As the program is a console application, I browsed to the .exe file, and created a shortcut for it as shortcuts can be set to be run minimized. The .exe takes the parameter of a string matching the name of your microphone device (if you have more) or “all” to toggle each one.


The last step is to configure pressing the eraser button on the Surface pen to launch this program.


Now I can relax back in my chair, not touching the keyboard, and mute/unmute myself as needed :)

Monday, March 16, 2020

Modern Script Editor web part now with support for Teams tabs!

Yeah, you got it, you can now use the modern script editor web part as a poor mans solution to bootstrap applications as a Teams tab. And the better approach is to develop a real Teams tab application – just so you know!

I did not really intent to do this, but I had a request to update the web part to SPFx v1.10.0 as some people have issues building SPFx v1.4.1 on their machines. While upgrading I figured I’d do a revamp so I updated the web part with a proper html editor and enabled Teams tab support as well – because why wouldn’t you right? (A shoutout to the PnP team for suggesting this).

Check out the readme from the below link if you want to test the Teams tab support as you need to edit some default settings to make that happen.



Side effect of mapping crawled properties to refinable managed properties

Image by Miguel Perales @ Unsplash

Mapping a crawled property to a refinable one is a common scenario in SharePoint search. If you expect the content behind the crawled property to also be full text searchable, you need to map the crawled property to an additional managed property which is set to be Searchable.


By default a crawled property is full text searchable. Meaning if the property contains the text “pnp is awesome”, then a query for the term pnp, will yield a result.

Once you map the ows_columnName crawled property to say RefinableString00, then the above query will not work as RefinableString00 is not searchable, and overrides the behavior of the crawled property. If you query for RefinableString00:pnp as a property query you get results as RefinableString00 is queryable.

If you want the content to be both full text searchable and to be used in a refiner, create a new managed property, for example named TotalRecall, and map ows_columnName to this property as well. Remember that a crawled property can be mapped to any number of managed properties, and something you might want to do especially when mapping them to refinable managed properties.


Wednesday, February 12, 2020

Set a document to open in view-only mode by default

Document productions and lifecycles come in many shapes and fashion. One scenario is sharing a document without the intent for the reader to necessarily make any edits or comments. To reduce the footprint of auto versioning and accidental edits of a document you have the ability to explicitly make the document open in view-only instead of in edit mode.

Other people may still edit and comment the document, but they must first make an explicit choice to do so.

If you didn’t know about this easy tip, here’s a video showing how you enable it using Word Online. The same setting is also available via desktop clients. If you already knew how, then you’re all set :)

Wednesday, January 22, 2020

Retrieving thumbnails/previews for SharePoint files and pages via Microsoft Graph API’s

Back in 2011 I wrote a post about thumbnail previews in search via the Fast Search for SharePoint which relied on Office Web Apps to provide the actual thumbnails. Fast forward to 2020, visualizing a page or document in a roll-up scenario is still valid, and fortunately todays service allows much better resolution on the thumbnails.

The API itself is coming via the Microsoft Graph and works on driveItems and is well documented at https://docs.microsoft.com/en-us/graph/api/driveitem-list-thumbnails.

If you want to test this out yourself, download the SPFx sample from https://github.com/SharePoint/sp-dev-fx-webparts/blob/dev/samples/js-msgraph-thumbnail/README.md to get started.


Digging into the API’s, the approach I have chosen to go from a SharePoint item to a Graph item is to use the site id, list id and item id – all id’s easily available per SharePoint item, either via REST API’s or the search API, using the calling signature below:

<endpoint>/sites/<site id>/lists/<list id>/items/<item id>
/driveItem/thumbnails/0/<custom size>/content

The above URL can be used directly in an <img> tag, removing the need for multiple calls in order to get the actual image.

Token Description
endpoint graph.microsoft.com/v1.0 (https://docs.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0)

tenant.sharepoint.com/_api/v2.0 (https://docs.microsoft.com/en-us/sharepoint/dev/apis/sharepoint-rest-graph)
site id Site object id – GUID.
list id List object id – GUID.
item id ListItem object id or unique id – Integer/GUID.
custom size See Requesting custom thumbnail sizes in the official Microsoft Graph documentation.

If you choose to get the drive item in a different way, that’s all good, as the thumbnail API itself would be the same. In addition to using custom sizes for the preview, there are also some default sizes you can use, all documented.

The above approach have been verified for most common file types (except Excel) as well as for modern pages.

Monday, December 9, 2019

Troubleshooting Search in SharePoint Online

coverOver the past years I’ve aggregated patterns and ways I use when troubleshooting why search results does not appear in the way you would expect. Some of it has appeared as blog posts, but for a while I’ve been thinking of putting it into a structured format.

Hence the book “Troubleshooting Search in SharePoint Online” was born. The book is a brain dump of my experience combined with help from others, and is means as a self-help book on investigating search issues before you go to the step of filing a support ticket. If you end up filing a support ticket, the process should be smoother as well as you should have aggregated good information on what you have tried so far :)

The focus is on why items appear or don’t appear, or are missing values etc., not why your KQL queries are not working as intended. Combined with my previous book on search queries, you should be armed with good tools to build and investigate search.

If you’re still using SharePoint on-premises, many of the concepts still apply, so it’s still a good read.

Where can you get the book? Head over to Amazon!

Wednesday, October 16, 2019

Breaking SharePoint search since 2013 – a lesson into unintentional consequences of messing with out of the box managed properties


I’ll start this post with a revised version of “Mikael’s managed property rule of three”, now called “Mikael’s managed property rule of four”:

  1. Never ever mess with the out of the box managed properties.
  2. Use automatic/implicit managed properties if possible.
  3. Map crawled properties (the plain ows_columnname ones) to the RefinableXXYY re-usable properties if possible. And do give them a unique alias for easier management and use.
  4. Create a custom managed property as last resort – which is only possible for Text and Yes/No columns.

Following these four rules will make your life easier, and help out troubleshooting search issues you might encounter.

Sometimes you think you know it all and then SharePoint search throws you a curveball. It’s been dormant all these years as it’s pretty much an edge case, but knowing this trick you can effectively break SharePoint search experiences quite magnificently :) Sounds fun right?

Note: You need access to the tenant search schema to break search experience globally, or employ this on your own site collections for mayhem and otherwise rendering yourself unpopular.