Saturday, March 17, 2018

Free screenreader for SharePoint

I'd like to share a short post on this thing I made: a screenreader for SharePoint.



What you're seeing is a standard Communication site in SharePoint on which I deployed a JavaScript component that reads aloud any page in your site, automatically or via the audio player controls at the top.
This shows the extensibility of SharePoint and might inspire you to help build an Intranet that is accessible for everyone in your organisation.
I've used SharePoint Framework, Microsoft Flow and the Bing Speech API to build it.
The code including installation instructions can be found on my github repository.

Tuesday, March 6, 2018

Trying out style transfer with Azure Notebooks

Perhaps I'm late to the party but only just discovered the cool things you can do with a style transfer algorithm which you can try out on https://deepart.io/ and http://ostagram.ru.

Here's an example:
This is my dog after style transfer
After doing some googling it turns out that the machine learning model is public property and can be downloaded. The academics behind it are Leon A. Gatys, Alexander S. Ecker, and Matthias Bethge by the way. I then found a blog that implemented it in a Jupyter notebook.

I wanted to find a way to use it in a web application of my own, so I tried to use Azure Machine Learning to run the code and create an API with it. I knew that Jupyter Notebooks were supported in Azure ML (although in preview).
After some trying out, I couldnt get it to work because I couldnt find versions of Pytorch and torchvision that worked with the version of Python that Azure Machine Learning uses (3.4.5).

I decided to give it a last try in Azure Notebooks. And it worked!
Turns out it uses Python 3.5 which Pytorch and Torchvision latest versions require, and the Notebook ran.

The cool thing about Jupyter notebooks is that you can mix all kinds of content like code, text, images and the output of the code. See the output of the last run of my notebook.
At the bottom you see the styled image. Too bad this is low quality, Azure Notebooks is not very powerful and it doesnt use a Graphical Processing Unit, which would be required to style high resolution images like it is done on http://deepart.io. Even with this low quality the algorithm takes 10 minutes to complete style transfer on one image.
Trying to get higher quality output results in extremely long processing times and errors due to RAM limitations. Being able to run it in Azure Machine Learning wouldnt have helpen anyway, since it also doesnt support running code on GPU.

If I would want to create a real Web App like deepart.io from this Notebook I would need to use one of the Azure Datascience Virtual Machines. Sadly, they cost about 30$ a day to run, which would max out my bankaccount pretty soon. So, not a viable option for a hobby project :-)

If you want to try out the notebook at the Pytorch blog then you need to take into account that the images you supply to it need to be perfectly square and they both need to be of the exact same resolution. But if you follow the blog and first try it with the two demo images picasso.jpg and dancing.jpg then the notebook will run in Azure Notebooks without a problem.


Run PowerShell on SharePoint from Azure Automation

Here's a quick instruction on how to run a PowerShell script in Azure Automation on a SharePoint site. Bonus: use the new preview action in Microsoft Flow to call the script.

Use case
If you need to change some settings on a SharePoint site it's easy to do this with PnP PowerShell. For example it could be that your newly provisioned sites need some updates that cant be done during the site provisioning proces because you dont use PnP Core, or not the latest version.
By calling an Azure Automation runbook from Flow you can even trigger the PowerShell script after your site provisioning process using Microsoft Flow has finished, and update the desired settings in the site.

You will need the following to complete this tutorial:
- SharePoint Online and an account that has at least site collection admin rights
- An azure subscription.
- Some knowledge of PowerShell is useful.

Let's go!

Start in Azure:
1. Provision Azure Automation in a resource group
2. Go to modules > gallery > Add SharePointPnPPowerShellOnline
3. Go to credentials > Add credential named SHAREPOINTADMIN and fill in your SharePoint online account username and password.

The account needs to have the permissions in SharePoint that the script(s) requires of course, but it doesnt necessarily need sharepoint farm admin rights.
Site collection admin rights are enough if you want to run the script on a single SC.

4. Add a Runbook and fill in this script. This is an example script that can update the sharing settings of the site. Save and Publish it. Use the test pane to see if it works.
Take note of the following lines:

$cred = Get-AutomationPSCredential -Name "SHAREPOINTADMIN";
Connect-PnPOnline -Url $siteUrl -Credentials $cred;

This gets the credentials you have just added to Azure Automation and uses the SharePointPnPPowerShellOnline commandlets to connect to SharePoint.
After this you can use any PnP PowerShell commandlet you want on that site collection.

In Microsoft Flow:
6. Open Microsoft Flow and create a new empty Flow.
7. Select the trigger you require. I'm using the simplest trigger which is Button for Flow.
8. Add an Azure Automation - Create Job action and select the AA account you have just used. Select the runbook and fill in the parameters.
9. Run the Flow and check in AA if the script has run successfully and in SharePoint if the settings have been applied.

PS:
The Create Azure Automation Job action in Flow is in preview. It doesnt work correctly 100%.
For example, you will often need to reselect the values you set in the action when you edit the Flow.
Also, the parameters of the Azure Automation runbook are not always fetched correctly. Save and leave the Flow, or reselect the runbook in the Flow action in order for Flow to show the correct input parameters.
Lastly, The Create Job action can't send boolean type variables correctly to the AA Runbook yet. That is why I've declared all my variables in the Runbook as strings or integers and cast them to booleans in the script itself.
This is a limitation of the Flow action which I assume will be solved shortly.
Dont forget to save and publish the Azure Runbook. If you change the parameters of the runbook you will need to edit the Flow and update the parameter values that you input.

Add the SharePoint PnP PowerShell module in Azure Automation

Add the credentials to SharePoint in Azure Automation 
Use the Create Job action in Microsoft Flow to call the script and pass the parameters.



Sunday, January 14, 2018

Send Email using SharePoint and MS Flow without Exchange

In this post I will (concisely :-) describe how to send a mail to a SharePoint user from Microsoft Flow in case the standard MS Flow send mail action doesn't work for you. This can happen if you don't use Exchange Online yet. Not a very normal case probably, but hey, maybe it'll help someone.
This also works for external accounts.

First you need to add the users you want to send mail to in a user group on a SharePoint site. This is required as the webservice we'll be using gets the user account info from a hidden list on the site that should include the user and his or her email address. So add the account to the site. The user doesnt actually need any permissions on the site, but the SharePoint site needs to 'know' the user.

Now before we can create the Microsoft Flow, you'll need to setup a SharePoint App on the site that we'll use the credentials of to send the email from Flow. Because we're going to call a SharePoint API from outside SharePoint we need a valid access token to be able to do so.

The method to get a valid token in a Flow described in an older post of mine: Call any SharePoint REST API from Microsoft Flow. It is based on the article Access SharePoint Online using Postman that clearly explains how to register an App in SharePoint to get a client id and client secret.

So see those two articles on how to get the token. You will need to call a specific URL with the client id and client secret passed to it in order to get an access token back. If you follow the previous post you will end up with a Compose action that contains the token string.

The final action is a HTTP Post to:
https://yourtenant.sharepoint.com/sites/siteyouregisteredyourapp/_api/SP.Utilities.Utility.SendEmail

with headers:
Accept: application/json;odata=verbose
content-type: application/json;odata=verbose
Authorization: Bearer <add the output of the compose action that holds the token here>

and the body:
{
                "properties": {
                    "__metadata": { "type": "SP.Utilities.EmailProperties" },
                    "From": "jurgen.wiersema@domain.nl",
                    "To": { "results": ["jurgen.wiersema1@domain.nl"] },
                    "Body": "Boe!",
                    "Subject": "Test flow email"
                }

}

In order to mail external users, you need to add the User Principal Name to the To property in the JSON, e.g. "i:0#.f|membership|jurgen.wiersema_gmail.com#ext#@jwiersem.onmicrosoft.com". This account needs to have the external mail address set in its profile of course.

Additional considerations:
- The user needs to have been added to the SharePoint Site you call the SendEmail webservice on. You can automate this within MS Flow by calling a different REST API method, which is the EnsureUser method.
- If you want to re-use this Email users Flow functionality, then you can build the Flow as HTTP triggered. If you pass the JSON above into it, which you then use in the action to post to the webservice, then you can re-use this Flow in all your other Flows by using a HTTP Post action to the Re-usable Flow URL.

Get token HTTP call

Send Email through a REST call - 1

Send Email through a REST call - 2


Email received by external user