Presentations at the Digital Workplace Conference Australia 2019 I’m looking forward to

It’s really exciting for me to be back at the Digital Workplace Conference again in 2019, this is one of the first major conferences that I was very fortunate to be able to present at, and I have always looked forward to attend, to learn and to give back and present the latest happenings in SharePoint, Office 365, Azure and now also Power Platform.

The Digital Workplace Conference will be on August 6-7 in Sydney.

DWCAU-temp-dates.png


This year I’m presenting a topic (and sorry for the slightly concatenated topic name):

A quick introduction to Microsoft Flow, but rapidly takes audience deeper to see the possibilities of the types of solutions possible


There probably should be a line-break in there somewhere. You have to use your imagination for this title for that missing character, sorry!

Lets try that again!

An introduction to Microsoft Flow: Office 365 - Automated

This is an introduction session on Microsoft Flow, but my aim isn’t to show you a simple alert email. My aim is to explain that we have far transcended “Workflows”. It’s not just workflow. We are way beyond that - what we really have is a full Automation Engine. It is Office 365 - Automated.

Be very careful, writing Microsoft Flow is completely addictive.


The Sessions I want to see!

  • Become The Expert of You – Power Skills for Personal Development - Heather Newman

  • Trust-Based Corporate Culture: How to Kick Fear and Toxicity Out of the Workplace - Heather Newman

  • The Fruit Salad Formula for Implementing Ofice 365 - Debbie Ireland

  • Microsoft Teams Deep Dive – 29 Practical Tips and Tricks - Lee Stephens

  • Making Teams work without understanding Information Architecture - Alistair Pugin

  • A Zero-Hype Introduction to Artifical Intelligence and Machine Learning - Kilash Awati

  • Adding voice interaction to your apps - Brian Farnhill

  • Give your PowerApps and Flows some Vision, Language and Feeling - Rich Burdes

  • How to build a Project Hub with Hubsites and Sitedesign and Sitescripts - Knut Relbe-Moe

  • Success Factors in a Thriving Yammer Network - Rebecca Jackson

  • How to Govern PowerApps and Flow - Paul Culmsee

  • Governance & Adoption for Microsoft 365: Making the Marriage work - Megan Strant

But that’s not all

I’m at the conference both days and plan to hang around for the workshop day too. So if you have any questions on

  • Microsoft Flow, PowerApps, Power Platform Governance solutions

  • Azure LogicApps, Azure Functions

  • SharePoint, PnP, Microsoft Graph, SPFx

  • Flow Studio startup journey

  • The latest imaginations in the mind of a mad man

And whatever in between…
I’m available for a chat!

The value of a Physical Conference

I always feel the top value of a physical conference is being able to stash away two or three days to focus and immerse in an environment with like-minded people, we talk tech, have the same challenges, but may have solved some of them with our own personal takes of that experience.

We are very much alike - when we are together in the same conference - we are introduced to new ideas that gives us a much broader perspective than we would usually see when we are so focused on our immediate day to day business problems.

I treat it as a relaxed edu-vacation. Seek out the sessions that broadens my capacities. And grab hold of the presenters and get a deeper discussion to take that back with me.

I would love to see you (see you again) at the Digital Workplace Conference 2019. If you see me you should say Hi John - I want to ask / I want to tell you about <THIS THING>

Decode InfoPath attachments with a bit of JS AzureFunctions

Serge, April and me were discussing a problem with pulling out InfoPath Attachment from InfoPath form XML and writing them into a SharePoint document library.

This is a problem I tried to tackle before, but came to realization that I would need an AzureFunction. The main reason is that the InfoPath attachment is a base 64 byte array but the byte array has a variable length header that includes the attachment file name. Flow doesn’t have amazing byte manipulation or left-shift abilities. So we need to write an AzureFunction to help.

As I brood over the problem I also thought it might be easier to handle the byte array with JavaScript. So I gave it a go.

This blog is my version of the answer.

The original decoder code in C#

There is a pretty old MSDN article on the C# code

private void DecodeAttachment(BinaryReader theReader)
{
  //Position the reader to get the file size.
  byte[] headerData = new byte[FIXED_HEADER];
  headerData = theReader.ReadBytes(headerData.Length);

  fileSize = (int)theReader.ReadUInt32();
  attachmentNameLength = (int)theReader.ReadUInt32() * 2;

  byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
  //InfoPath uses UTF8 encoding.
  Encoding enc = Encoding.Unicode;
  attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2);
  decodedAttachment = theReader.ReadBytes(fileSize);
}

The updated code in JS AzureFunctions

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    if (req.body && req.body.file) {
        // https://support.microsoft.com/en-us/help/892730/how-to-encode-and-decode-a-file-attachment-programmatically-by-using-v
        var buffer = Buffer.from(req.body.file, 'base64')
        //var header = buffer.slice(0, 16);  // unused header
        var fileSize = buffer.readUInt32LE(16);  // test is 5923 bytes
        var fileNameLength = buffer.readUInt32LE(20);  // test is 13 chars
        // article lies - it's utf16 now
        var fileName = buffer.toString('utf16le', 24, (fileNameLength-1)*4 -1);  
        var binary = buffer.slice(24 + fileNameLength * 2);
        context.res = {
            // status: 200, /* Defaults to 200 */            
            body: {
                fileName: fileName,
                fileNameLength: fileNameLength,
                fileSize: fileSize,
                fileContent: binary.toString('base64')
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a base64 file in the request body"
        };
    }
    context.done();
};


The InfoPath form


The Microsoft Flow that coordinates the work


Results

  • Need Azure Function here

  • JavaScript buffer is pretty good at doing byte decoding, easy to read too

  • Debugging and tweaking the byte offset is quite a bit of trial and error, was not expecting that. May be that MSDN article is too old, it is from 2003.

  • You may think - John 2018 is not the right year, or decade to be writing about InfoPath. But hear me out. As companies move their form technology forward, they will need to consider how to migrate the data and attachments in their current InfoPath forms somewhere - having this blog post as a reference is important for that eventual migration. Good luck!

From Office 365 to Azure Event Grid, the events must Flow

Photo by  Archana More  on  Unsplash

In this blog post, we capture all the events across an Office 365 Tenant from multiple event sources, gather them, and send them through an Azure Event Grid.

We then listen, filter and handle our events in a central, unified way.

The events must Flow.


This is also the full write up of this microblog posted to Twitter #FlowNinja earlier this month.


Plan

  1. What benefit do we get from this?

  2. Listen to every event across an Office 365 Tenant

  3. Construct a uniform event message

  4. Send them into a Serverless Event Solution - Azure Event Grid

  5. Filter and catch our events

We want to build 3 Flows

flow-event-grid-1.jpg

What benefit do we get from this?

First, we see the increasing availability of event hooks - we have subscriptions, delta queries, or webhooks, across various different products in Office 365. Some products like SharePoint is getting a SocketIO webhook. There will be more events, and our event handling design must evolve.

Second, we see the cost-effective solutions to handle these ever increasing flood of events in the form of Serverless compute. This is true with Azure Functions, Microsoft Flow or Azure Logic Apps.

We end up with a lot of individual event sources and a lot of individual event receivers. This is a common event handling problem. As number of events we handle increases, the worse the event management problem becomes.

Consider you have a “handle a document uploaded to a library” event - a very typical SharePoint Workflow. Now consider this library is cloned to a hundred project sites.

If we clone the event handler a hundred times, we have a problem.


If you have already done this with Flow, then try https://FlowStudio.app to help you manage them.
Ooh inline product placement!


If you are a developer, then consider this scenario.
Consider a typical event handling in the browser. A decade ago we used jQuery like this:

// 2008
$('button').click(handler);

// 2018
$(global).on('click', 'button', handler);

And gradually we find that unacceptable, because we have buttons, events everywhere, and managing individual event hooks was tedious and error prone. Eventually, we moved to a global handler model, and we filter just prior to event being raised.

The headache-less way to handle events is to set the hooks all at the global root level, and then filter by the event source and event type.

That is the exact reason we need Azure Event Grid.

  • Centrally manage our events

  • Decouple the event source from event handlers

  • Stay sane, with a hard problem

Listen to every event across an Office 365 Tenant

I had previously wrote about listening to Office 365 Management API via the HTTP action and app-only permissions. What I did not realize was that the Office 365 Management API also have fantastic webhooks.

I read about the webhooks from Kent Weare’s post, where he uses this event to get a trigger when Flows are created in the tenant.

https://flow.microsoft.com/en-us/blog/automate-flow-governance/

These are grouped into several categories: AzureAD, Exchange, SharePoint and General (other).

This is the subscriber. One picture of 4 blocks. I’m subscribing to three webhooks at once.



The Office 365 Management API is a fantastic general event source. The downside is that it’s not instant - event handler is called between 10-20minutes after the actual event. So it is great as an audit webhook, or for scheduling files or search or to signal for a bot to re-scan a document. But it’s not an instant webhook.

Of course, if our goal is to send events into an Event Grid - we can work with multiple event sources at the same time. We can add Microsoft Graph events or subscribe to SharePoint list webhooks directly.

This is the top of the Listener

Construct a uniform event message

The event grid has a event JSON structure, it also supports a CloudEvent structure.

When I built my implementation, the Event Grid connector is still in preview and I had troubles publishing a Cloud Event structure. I assume this wouldn’t be a problem anymore as the connector evolves.

This is the final loop design - all done.

Remember, we are running Serverless so abuse/utilize every opportunity to use as many Azure Servers as you can - if you can fan-out to parallelism you must.

Don’t talk to each individual HTTP action one at a time. Do (up to 50) all at the same time.


Send them into a Serverless Event solution - Azure Event Grid

The Azure Event Grid is a serverless event processing pipeline. It decouples our event source(s) from our event handlers.

Here is our first handler.

This catches every event on the Event Grid - in Event Grid, we see we have our first webhook attached - it appears as a LogicApps webhook.

Here are three examples of what it caught:

  • Flow created Event

  • Site Collection created Event

  • File uploaded Event

flow-event-grid-3.jpg

Filter and catch our events

We see the very specific webhook now registered on the event grid - and the filters are also listed

PPTX filter only runs when the file I’ve uploaded is a PowerPoint file.


Summary

I have been talking a lot about Serverless and how our tools and design must evolve. Having a unique Office 365 to Event Grid solution is something I talked about as far back as 2017. I’m glad a year later I’ve finally got a great prototype going.

  • Office 365 Management API is a great webhook source that catches all sorts of events. The downside is that it is an audit webhook, so the delay may not be acceptable to your needs.

  • Using Azure Event Grid to perform filtering and subscription gives us the unique ability to see EVERYTHING that’s going on in our tenant. That has tremendous value.

  • Because event source and event handling is now decoupled - we can add new event sources to push to the same Azure Event Grid. We can do this from Microsoft Graph, we can do this from SharePoint, or we can do this from a whole myriad of triggers available in Microsoft Flow

  • We can write Azure Functions to trigger off the Event Grid, and it would be visible as well.

  • I was reading and appreciating sending events to the new Azure SignalR service from Azure Functions - that would be pretty amazing to convert an event grid message into a websocket event.
    https://twitter.com/nthonyChu/status/1044427579460145152

The possibilities are endless. Our tools and our design must evolve.

Speaking and Hackathon at Digital Workplace Conference Australia - Melbourne

DWCAU-Landscape-Temp.png

In a little less than a month on August 15-16, I'll be presenting in Melbourne at the Digital Workplace Conference Australia 2018.  

www.dwcau.com.au

(I still fondly remember this conference as the previously annual Australian SharePoint Conference - but all things evolve.  SharePoint to SharePoint Online to Office 365, and the workplace evolved from portals to intranet to social platforms to conversational platforms).

Flow and Functions: level up our Serverless Toolkit in Office 365

I will be presenting an amped up talk covering the implementation and automation with Microsoft Flow and Azure Functions.  This is one of several sessions on Microsoft Flow at this conference so I will be covering implementation and mastery at level 200+  (But because it's Flow, it'll still look deceivingly simple!)


John join forces with Paul Culmsee and Ashlee at #DWCAU pre-conf hackathon

I want to also mention that I'm helping out with Paul Culmsee and Ashlee's PowerApps and Flow Workshop/Hackathon on 14 August 2018

http://www.dwcau.com.au/workshops/powerapps-hackathon/

I personally don't know how much PowerApps and Flow raw potential would be in that room in the hackathon.  I really want to find out and I hope you would too.  Space for this is limited - please consider this one day pre-conference workshop.

"Learn PowerApps and Flow from experts and build an app that you need." says John.

"Two MVPs for the price of one" says Paul.  I'll just leave this here.

Whether at the conference, and/or the hackathon, I hope to see you there in Melbourne.

Run Any PnP-PowerShell via Drag and Drop Zip to AzureFunctions

pexels-birthday-box-celebration-45238.jpg

So I previously asked aloud "Can we simplify this further" - It turns out you can.  You can deploy a PnP-PowerShell from scratch in 1 minute.

And since we are targetting completely non-devs.  We do this via dragging and dropping one Zip file.

 

Plan

In my mind - yes.  Yes that installation could get simpler.  App Services (because of the Kudu backend) supports Zip Deploy.

https://docs.microsoft.com/en-us/azure/azure-functions/deployment-zip-push

But a quick read of the article it targets DevOps doing zipdeploy with Azure CLI, REST or PowerShell.  There's nothing for a yet-to-be-developer.  What I wanted to do was drag and drop zip deploy (so I quickly reached out to Ling Toh and turns out she says she does it all the time).

Steps in Pictures

1. Grab this ZIP file 

https://github.com/johnnliu/azure-functions-o365/blob/master/Run-Any-PnP-PowerShell.zip

2. Create a new Functions App

3. Drag and Drop zip file into Kudu

4. Configure App Settings

Back to Functions page under Azure Portal.  Refresh and you'll see the function appear.
Go to app settings to set up the USER/PW variables we need for the test.

5. Test it

Summary

That's it really.  Drag and drop deploy of a function via ZIP file.
Feel free to open up the zip and see how all the pieces are laid out, including the entire PnP-PowerShell module dependency.