Showing posts with label sharepoint. Show all posts
Showing posts with label sharepoint. Show all posts

Tuesday, March 5, 2019

You have been judged

Arctic Cloud Developer Challenge was amazing
As you may know I was a judge during this years Arctic Cloud Developer Challenge (#acdc2019)
It was a fantastic event with a lot of great content created by the participants. This year was The Simpsons themed and all the teams did a great job creating solutions with a related branding. This year we had special categories for security vulnerability, ethical hacker and black hacker, which would give you negative or positive points. These categories were not overly used, though the Swedes managed to set everyone back 50 points at one time.
We also had one lightning challenge per judge, and while I outsourced mine to the fantastic Elaiza Benitez the other judges chose some really cool scenarios.
For this event we got some really cool MX Chips from Ben Vollmer, my favourite person in Microsoft, and we handed out 1 to each team so they could use them for the IoT category. All the teams were actually doing IoT stuff, which I think is really awesome. IoT is one of the things I believe will be part of everything in the future, in fact I think the abbreviation will disappear in time and we will just take it for a given that everything around us is connected, so I was very happy to see that all the teams made an effort.
We had 3 judging sessions over the three days, where we would give out points to each time in each category, and the winner of a category would get a crown to show off that they are “the ones to watch” for that category. On the second and third day we would collect the crowns and hand them out to the new winner. By the end of the second day the Three Eyed Fishes (Skill) were clearly in front with quite a few points, and I think a lot of the teams got nervous.
On the final day the teams went into full focus mode, and the mood was very intense for several hours. Unfortunately for the Three Eyed Fishes they lost 2 team members the last 24 hours due to family situations, so they had a huge handicap in terms of planning and redistributing responsibilities among the other members, and the competition did not slack off in the face of potential victory.
After the third and final judging the new team scores looked much more even, and the popular vote points could swing it any direction


The teams got 10 minutes to present their solution, and at the end all the attendees, judges, guests and organizers got to vote for their favourite. Each vote counted 15 points, and the teams could not vote for themselves (which would give them 15 minus points). It was really close, but in the end the Swedish Snowballs (DQC) brought home the victory by a margin of 55 points over the Three Eyed Fishes.

This was an amazing performance by the Swedish Snowballs, as they went from last place to first place in 24 hours. The big thing about the final day was that each crown was worth 100 points, so winning any category on the final day would not only give 100 points for the category, but an additional bonus of 100 for going home with the crown. The Swedish Snowballs managed to capture three crowns, and here’s a quick overview of which and why
  • The Genesis Tub (IoT category): The first two days they struggled a lot with their devices, and they brought quite a few of them to the show. However, on the third they had worked through all their issues, and they had 3 working Raspberry Pi units placed around the venue with cameras, looking for Nelson to try and avoid him. The main thing that swayed the judges was the fact that they had experimented with facial recognition for a long time, and finally decided to move the processing off the pies and created an online service which did all the processing for them. This got the processing time down from well over 10 seconds to around 1 second, making it a much more fluid solution. This is a great demonstration of how IoT edge devices should not be assigned the responsibility of processing, but only do the work they were meant for (image capturing and motion detection in this case).
  • Obey the Hypno Toad (UI+UX): The entire interface was built in react, which means it worked great on all devices when they first got it working. However, they made sure to go the extra mile by taking Simpsons sprites and animating them, and they created custom icons for picking a character. Additionally, they added an alert system which included audible and visual alerts, so you would get notification if Nelson was spotted on your path. They also considered that iOS removed alerts from their latest updates, so while platform alerts worked on Android and Windows, the iOS devices would get a visual notification on the top of their screen, which managed to be informative without getting in the way of the map navigation. In other words the UI was not only visually nice to look at, it was also designed in a way which would be possible to integrate into the display unit in a modern car without obstructing the navigation.
  • Automated Teller Machineyolatrolamaton (business value): The reason for winning this was that they had several clear, understandable business scenarios for their solution. It was something they could use for Safari tours and parks to make sure that people could go where the animals were. It could also be used to warn people about dangerous animals in an area, to identify poachers, to create evacuation routes in a natural disaster situation, etc. Additionally, it was working and deployed to a public web site, so the product was ready for sale at the time we went around judging.

As judges we were very impressed with all of the solutions we were presented, and I oblige you as a reader to take a look at the Arctic Cloud Developer Challenge blogs to see what all the teams built. https://acdcblog.azurewebsites.net/
Finally a big shout out to the sponsors for making this event possible, it is probably the most awesome hackathon in the
Now I just have to cross my fingers and hope to be invited to this awesome event again

Wednesday, January 3, 2018

Using flow to automate document locations in Dynamics 365

I recently had the following requirement to solve in Dynamics 365

When a customer (account only) is created a new Teams channel should be created.

All documents regarding the customer should be put into this channel folder in a specific group.

This should happen automatically, and be easy to maintain and support.

I decided to solve this in Microsoft Flow, as this seems like the type of problem it is meant to solve, and the following is the brick walls I ran headfirst into trying to get it working.

Prerequisites:

  1. Server side document integration enabled
  2. Group site added to SharePoint sites
  3. Documents (Shared Documents) added as SharePoint Document Location
  4. Guid of the document location record in Dynamics


Creating a flow which triggers on account creation

image

Starting out I create a new flow from blank, and set the trigger to “When a record is created” in Dynamics 365. If this is the first time you create a flow then you might get a JSON error message in the organization drop down. To work around this simply go to “Connectors” from the toolbar, and find the Dynamics 365 connector. Click on the “When a record is created” trigger, and a flow editor will start with a working Organization drop-down.

Select the organization you want to connect to, and then choose Accounts from the Entity drop down. If this is the first time you use the Dynamics connector it can take a minute or two before the drop down is populated.

Creating a channel for Microsoft Teams

My first thought was to create a condition to check if there already is a channel with the same name. Unfortunately, the only actions for Microsoft Teams as of today is “Create a channel”, “List channels”, “List teams” and “Post message”.

image

While List channels might sound like a good way to check whether a channel exists, you’re getting all the channels from a specific team without filters. This also means that looping through the list will generate a lot of unnecessary actions in Flow (which again might start to cost money if you’re not careful). An alternative, as Mikael “I dare you to ask me about search” Svenson pointed out is to write your own formula to check the content for an existing channel. The result looks something like this

image

This works fine, but the formula used is barely human readable, and not something I feel comfortable leaving at a customer’s environment to maintained by someone else. I decided to try and strong-arm the Flow into doing what I wanted instead.

I put in the “Create channel” action, where I pick the team Id and I set the display name to the Account Name from the MSDYN365 trigger. This means that every time an account is created, a corresponding channel is created. Next I hit Save flow and Done.

image

Testing channel creation

First thing I did was create a new channel in teams. Then I replace the account name in the “Create a channel” action with the same name. I did this is to see what happens when it tries to create an existing channel. Creating a new account which triggered the flow produced the following error:

image

So when we try to create an existing channel we get an error 400 telling us that the channel already exists. That’s great, that means we have a good description that we can use in a condition to handle existing channels.

We’ll create a new Condition from that step, change to advanced method and paste in the following formula (if body contains NameAlreadyExists or does not contain “error”:)

@or(contains(body('Create_a_channel'), 'NameAlreadyExists'), not(contains(body('Create_a_channel'), '"error":')))

Then click on the elipsis (…) and click the “Configure run after” option, and make sure both “is successful” and “has failed” is checked. It should look something like this

image

In the failed step you can add actions to notify when an unexpected error occurs, for this example I’ve chosen to notify myself whenever the condition is false, where the formula for the email body is:
body(‘Create_a_channel’)

Next I add a Terminate action to prevent the flow from processing more steps. The result looks like this

image

Creating a new document location in Dynamics

After we’ve handled errors on creation of a new Teams channel, we have to create a new document location in Dynamics. Add the “Create a new record” for Dynamics 365 action. Choose the organization you’re working with, and choose Document Locations as the entity name.

Click on the Show advanced options expansion link to enable filling out everything we need.

  • Organization Name –> Select the organization you’re working with
  • Entity Name –> Document Locations
  • Parent Site or Location –> The Guid of the Documents (Shared Documents) record in Dynamics (prerequisites in the beginning of this post)
  • Parent Site or Location type –> Select sharepointdocumentlocations
  • Regarding –> Expand the “When a record is created” selection from the dynamic content, and select Account (Unique identitifer of the account)
  • Regarding Type –> Select accounts

The end result should look like the following:

image

Creating a SharePoint folder

Testing the flow it looks like everything runs fine, and checking in Dynamics we can see that the document location has been created successfully. However, if you try to browse to the document location on the account created you get an error message saying that the folder does not exist in SharePoint. After poking around a bit I found out that creating a Teams channel from Flow (which in turn uses the Graph API) does not create a corresponding folder immediately. Instead, it is picked up by some timer job in the backend. I feel like that is kind of risky business, so I decided to create the folder manually to speed up the process, and prevent unnecessary error messages in the user interface.

Unfortunately, there is no way to just create a new folder in a document library using Microsoft Flow. This left me quite frustrated until I found out that creating a new file will create subfolders automatically if they don’t already exist. We’ll use that feature to create the folder for us, by creating a new dummy file.

Start by adding a new action above the “Create a new record” action, and choose the “SharePoint – Create File” action. Choose the site for the Group you want to work with, and in the folder path type /Shared Documents/, then append Account Name from the dynamic variables. Name the file deleteme.txt, and type some useful content should it fail to be deleted.

image

Now, create a new action beneath this one and select “SharePoint – Delete File”. Select the site where the file was created, and for File Identifier select Path from the “Create file” action.

image

The entire flow should now look like this

image

Taking this beauty out for a spin

To test out our new flow I created a new channel in Teams first, then created a new account with the same name as the channel. After a short while the flow triggers, and I can see that it fails on the create channel step, but it hits the “if yes” condition because it’s an existing folder, and the result says success.

image

I create another new account with a name that doesn’t exist as a channel already, and this time all the blocks are marked with green check marks

image

Summary

So there you have it. A flow which automatically creates a new channel in teams and adds a document location to the Dynamics 365 account so you can share and collaborate on documents.

Wednesday, October 11, 2017

SharePoint retention policy and Office Groups, part 2

In the previous post we looked at how to create a label and apply a policy.
In this part we're going to look at how this will work in a real life scenario.

Labeling content

First of all lets head into the Office Group we created, and look at the site collection overview. I'm saying site collection, because that's basically what it is, but unlike traditional site collections it's not available through SharePoint admin, and it has some extra settings to it. But don't take my word for it, check out Mikael Svenson's blog for a lot of amazing content on everything Office 365.
Opening up the site we see that there's nothing special going on here. It's an empty landing page with the only activity being the creation of the group and the document we uploaded (at least I did).

Going into the documents section, we find the file uploaded in the previous post (or you can just create a new file here). Click on the vertical ellipsis, expand the More category, and click on Compliance details.
This will show you a screen that looks something like this:

Click on the "None" link for the Label status. This will open a page where you can specify the label for this document. Go ahead and select the label we created in part 1, and then hit save.

Deleting the document

Now that we have a document with a label, let's try to see what happens if we try to delete it.
Click the ellipsis and select delete, then click Delete in the confirmation box.
If you set up the archive policy like me, you should be presented with the following message

Great, so that means the stuff we're saving cannot be deleted. We didn't select the checkbox for treating files as records (read-only), so we can still edit the document like we want.

Deleting the group

That's right, we're going to delete the Group already. We now have a Group with one document in it, and the document has a label which says to have a 2 year retention after the last modified on date.
Click on the cogwheel in the top right, then select Site information. In the side bar, click on the Delete site link, and then check the box which says "Yes, delete this group and all its associated resources.". Now click that delete button and cross your fingers.

Where did everything go?

If your tenant is like mine, the group was deleted and you were redirected to the SharePoint root site. Let's take a look around to see if we can find traces of the group.
Going into Outlook we can see that the Group is still there, which is just because Exchange handles these deletions on a schedule that nobody® knows how works. I'm going to go ahead and delete it from Outlook as well. Click on the down-arrow in the top right corner, then select Edit group.
Click on the Delete group link, and in the dialog window check the box stating "I understand that all group content will be deleted"


OK, now everything is gone? No, there's the the matter of the recycling bin. Unfortunately, deleted groups are not available through the UI, so you have to bring out some of your awesome PowerShell skills (or just copy the commands below). Now, I'm assuming you have a modern version of Windows with the possibility to install modules from the shell. If you don't, then you kinda have to do some internet research on how to install them for your environment.

Open PowerShell as an administrator and run the following commands to find a deleted group:

Install-Module AzureADPreview
You will get a warning about the repository, I trust the repo so I'm choosing yes. If you don't trust this repo then I'm afraid this is the end of the line for you, if not select yes and continue.

Import the newly installed module and connect to Azure AD, and then retrieve the deleted groups using the following commands

Import-Module AzureADPreview
Connect-AzureAD
Get-AzureADMSDeletedGroup -SearchString CrmVikingDoesSharePoint

For me that lists out the Group I deleted. Now, do delete the groups, simply run the following command

Get-AzureADMSDeletedGroup -SearchString CrmVikingDoesSharePoint | Remove-AzureA
DMSDeletedDirectoryObject -Id $_.Id

Group deleted, not a single warning presented.
This means that the retention policy provided by labels does not prevent Groups with the content to be deleted.
To recover a group, the following command can be run instead
Get-AzureADMSDeletedGroup -SearchString CrmVikingDoesSharePoint | Restore-AzureA
DMSDeletedDirectoryObject -Id $_.Id

Wrap up: OK, this seems weird.

So it seems that the retention policy set by using labels will prevent us from deleting files by mistake, but it certainly does not protect the site from deletion.
I'm guessing that there's some sort of logical mishap on the server side, because why would you force an administrator to verify that no content inside a group is set to be archived?

This tells me that the retention policies aren't quite production ready, and I have to find some other clever way to use Office Groups that helps reduce Outlook clutter while not deleting all content.

Until next time!