Cover by Kim Damsleth (Puzzlepart)
If you thought becoming an MVP is as easy as 1-2-3, think again – my story is all about pushing aside those who have been in my way and claiming what is mine! Don’t like it? Tough luck – I’m here to stay!
My musings on Office 365, search, programming and technology.
(June 1st, 2019, I started as a full time employee of Microsoft, thus any post before that date are solely written on my own behalf)
Cover by Kim Damsleth (Puzzlepart)
If you thought becoming an MVP is as easy as 1-2-3, think again – my story is all about pushing aside those who have been in my way and claiming what is mine! Don’t like it? Tough luck – I’m here to stay!
Ok, someone created an account for you on their Office 365 tenant for testing, and gave it no licenses what so ever. Yet, they did grant you permissions to access SharePoint Online. So, how do you find out what the SharePoint domain is? Because you have no apps in the app launcher or search box to help you out.
We mulled this over at our Puzzlepart dev chat channel, and Ole Kristian came up with the first solution:
Once logged into office.com, crank open dev tools in your browser and type:
navBarData.SPO_RootSiteUrl
This will yield the sharepoint domain name :)
Do you know a different way?
I decided to try out the Kindle preview web part, previewing my own Search Queries Explained book. When pasting the link I was presented with the following error:
And as the error message says, use the embed code instead of just the link. But would be nice if it managed to wrap this automatically, no? :)
When pasting the full <iframe> link it works as expected.
In SPFx v1.4.1 there was an important bug fix which was introduced in SPFx v1.4.0. If you created a web part which was manually installed on a site collection, upgrading the web part would result in the web part not showing. The issue noted on the release notes for v1.4.1 says in order to fix this do the following:
You don’t have to uninstall the solution, but can follow these steps instead:
Unfortunately there is no easy way to see all sites which have installed a particular SPFx v1.4.0 web part, so you have to loop over all sites in order to ensure they are all working as expected.
Photo by Mikael Svenson
If you haven’t caught on already, at Puzzlepart we love sharing our small quirky workarounds. This time around it’s a run-once extension which will set the logo for an Office 365 Group when a group owner visits the site for the first time.
Image by Jeremy Bishop at Unsplash
Phew.. that title was a mouthful. When SPFx v1.4.1 was released the other day, the GraphHttpClient object in SPFx was deprecated in favor of either the AadHttpClient object or the MSGraphClient object. If all you care about is Microsoft Graph calls, then they do pretty much the same, except the MSGraphClient object allows a fluent API to build up your queries with selects, sorts and filters, whereas the AadHttpClient takes a handcrafted URL.
So, from a minimal path perspective the AadHttpClient makes more sense as it takes complete URL’s, and we don’t have to break up the call into a fluid syntax. Also, the MSGraphClient is currently in preview.
Note: If your tenant is not on Targeted Release (TR), you will not be able to grant the needed graph scopes using the SharePoint Admin UI or with SPO Management PowerShell. Uploading the app package will also not work on a normal tenant so be patient.
Photo by David Kovalenko at Unsplash
Took me an hour or so to figure out why something I had ported from C# to PowerShell was not working, and the culprit is how casting of decimals to bytes work.
In .Net: (byte)4.6 = 4, meaning it truncates
In PowerShell [byte]4.6 = 5, meaning it rounds up
The solution is to use [Math]::Floor instead in PowerShell, which of course works fine in .Net as well.
Photo by Olu Eletu at Unsplash.
This is a short one and quite easy. When you create an item in SharePoint the unique identifier for a person field is the claim, while the Get Manager action takes a UPN (user prinipcal name).
For Office 365 they are almost equal. The claim is actually the UPN + a claim prefix.
UPN: john@contoso.com
Claim: i:0#.f|membership|john@contoso.com
If you have a flow triggering on a SharePoint list, you would enter the following expression for the UPN field to strip off the prefix from the claim.
replace(triggerBody()?['Editor']?['Claims'],'i:0#.f|membership|','')
Sure you can use the e-mail address which usually match the UPN, but you would be surprised how often multiple accounts have the same e-mail address - admin accounts, test accounts etc. So using a unique identifier is always a better approach compared to the e-mail address.
Photo by Oliver Thomas Klein at Unsplash.
Validating input in SharePoint is nothing new, but I haven’t dug much into this over the years. This time around I have a list where one of the fields takes a case number. The case number should be on the format:
0000/000000 <- four digits, a slash, then 6 digits.
Using regular expression this would have been a breeze - \d{4}\/\d{6} , but that’s not an option in SharePoint. Using the official formula documentation as a lookup I ended up with the following formula. I’ve split it over multiple lines and added comments for readability, so remember to remove the comments before using. Depending on your locale you might have to use comma instead of semi-colon.
Make note of the +0 which is workaround to convert text to a number.
AND( LEN([Case Number])=11; # Total length is 11 characters MID([Case Number];5;1)="/"; # Fifth character is a slash ISNUMBER(MID([Case Number];1;4)+0); # First four characters is a number LEN(TRIM(MID([Case Number];1;4)))=4; # First four characters has no spaces ISNUMBER(MID([Case Number];6;6)+0); # Last six characters is a number LEN(TRIM(MID([Case Number];6;6)))=6 # Last six characters has no spaces )
Validation is entered at the columns settings.
And here I only have 5 digits at the end, which does not validate.
Photo by Hans-Peter Gauster on Unsplash
I’m working on implementing a Flow which triggers on a SharePoint list. This list has a managed metadata column where you can select multiple terms. In my Flow I want to append the terms into a single string which I’m persisting on my Microsoft Graph schema extension techmikael_GenericSchema.
The approach I’ll outline does not only apply to taxonomy fields, but for any input which has an array of objects. Below is a sample object array.
[ { "TermGuid": "74c34307-80e8-4e21-a63b-81337e369a5c", "WssId": 29, "Label": "Term A", "Path": null, "Value": "Term A|74c34307-80e8-4e21-a63b-81337e369a5c" }, { "TermGuid": "db79ec09-34ad-4c60-8f4c-d41248ee09ac", "WssId": 450, "Label": "Term B", "Path": null, "Value": "Term B|db79ec09-34ad-4c60-8f4c-d41248ee09ac" } ]
The output should pick the Value property and join them together with a semicolon like this:
Term A|74c34307-80e8-4e21-a63b-81337e369a5c;Term B|db79ec09-34ad-4c60-8f4c-d41248ee09ac
Image by taner ardalı at Unsplash
More often than not I encounter the following scenario (and I suspect this is quite common in a lot of European countries): When a company’s tenant was created they chose their locale as the default language. This might not be an issue, until they remember that the official language should be for example English, which differs from the locale.
A good example is a tenant which was created in Norwegian. This often(*) leads to sites and Office 365 Group modern sites to have Norwegian as the default language, while having it in English would be ideal.
This post cover how to test multiple languages, and also how to force one particular language – as you might want to force different languages for different users. And, you cannot really force the language per site, unless for site collections and communications sites when you create them via an API.
(*) depending on how the site was created
Photo by Ben White at Unsplash
At Puzzlepart we believe that sharing is caring, and it’s pretty core in how we think about code and solutions. We contribute monthly to SharePoint PnP, but the two extensions released here are not really samples on how to use SPFx, but they solve concrete business problems.
We’ll start off with two extensions, and add more extensions and web parts in the time coming forward.
You can find the code at https://github.com/Puzzlepart/spfx-solutions
If you are working in an environment where the out of the box self-service of Office 365 Groups have been turned off, but you still want to create Teams for O365 Groups via some other provisioning solution – or give users an alternative to create the Team via the Teams client, this is the extensions for you.
By default in a public Office 365 Group every employee in your organization will have write access to the groups site. I believe you should be an explicit member of a group in order to produce content in it, so it makes more sense for a public group for everyone to have read-only access instead.
This extension sits silently on the group site, and when a group owner visits the site it checks that non-members have read-only and not contribute access. If the Everyone group somehow has been given contribute access, it’s moved back.
Photo by Lex Sirikiat at Unsplash.
When automating Groups provisioning and configurations some configurations cannot be achieved using app-only tokens, but have to be performed by a group owner.
Examples of this are setting the group logo or enabling Microsoft Teams for a group. This is where SharePoint Framework application customizers come in handy.
The idea is to run a piece of JavaScript once an owner enters the group site for the first time, and then remove the application customizer once run, as it’s not needed anymore.
I wrote a sample customizer for this which you can find at the PnP sample repository on GitHub.