Assign licenses to a group instead of user in Office 365/Azure

Ah, the joys of licensing in Office 365. Without a license, there is no just no fun in Office 365, you have no services available and without a service no option to be productive. There is a lot to be said about licensing in Office 365. You have license bundles like E3, E5, Microsoft 365 etc. that contain a bunch of services. You need to make sure you give people the right services they actually need to do their job. There are a lot of debates about whether you want to open all the services for all the users or not. Just based on these statements you can tell that assigning the right license is a very important task. To make this task a little more complex there wasn’t really a way to automate managing licenses to users except for PowerShell. Think about it, AAD Connect synchronizes your users, contacts, and groups with all their attributes from your on-premises but there was no option to manage the license assignment.

Until now.

Azure Active Directory, one of the most overlooked and underestimated services attached to Office 365, has the possibility to assign licenses to a group. Since the documentation is excellent, thank you Microsoft, I don’t think it makes sense for me to go into detail in the how.

Side Note: this functionality is only available (for now) is the Azure Portal, not in the Office 365 Portal

AutoUpdate based on membership

What is very interesting is that licenses are kept up to date when user memberships change for the group, the licenses for those users are updates as well. This methodology allows you to manage your licenses (and therefore your active services) by adding and removing users to and from groups.

Migration from direct to inherited through groups 

How do you convert from direct to group based? There are like always multiple methods but something that I like to use is this structure.

  1. Create your groups and make them available in your Azure Portal (e.g. with AADConnect when sync is needed)
  2. Setup your license assignment per group
  3. Add your users to the groups and sync if needed
  4. Check for conflicting licenses (see next paragraph) and solve them
  5. Remove the direct licensing

Conflicting licenses

Unfortunately, there are licenses that don’t like being together, these will cause licensing conflicts. Luckily when there is a licensing conflict the original license will stay in place and you have time to fix it. An overview of the license SKUs and which one will cause conflicts can be found here:

PowerShell for Group Licensing


Azure Active Directory activates MFA for elevated user accounts (admins)

You probably haven’t noticed anything (yet). But Microsoft has created a rule in Azure Active Directory Conditional Access called Baseline policy: Require MFA for admins (Preview). Read the Microsoft post here. I am a strong believer in security and that doesn’t change because we are currently using a cloud service like Office 365. Elevated accounts like admins should be using MFA. Microsoft supports that statement by implementing this new policy. The reason why you haven’t noticed anything yet, is because in the preview stage, Microsoft decided to opt you out unless you activate it in the policy. When it goes in to GA, it will be reversed to opting in unless you deactivate it.

Now what is going to be the impact? Easy, all types of admin will have to use MFA to get access to the Office 365 services. But what about scripts, service accounts, etc? The policy gives you the ability to opt out certain accounts, so I would create a group with all you admin users that you use for automation or service accounts.

Now, a lot of people are going to complain that this is going to effect their end-users. To those people I tell them this: Why do your end-users have admin accounts enabled? I strongly believe in a separation of duties and accounts. If there is a part of of my daily tasks that require me to have an elevated account, make sure I have an separate account that has those permissions. Elevating your permissions should be a conscious decision and if your account is always elevated it is not. The possibility of doing something wrong is too real when you don’t separate your accounts.

Make sure to investigate before it goes in GA

Security and Office 365 through Secure Score, download my eBook.

Let’s just drop it here. It is finally here. My first eBook/white paper, whatever you want to call it around Office 365 and Security. If you don’t want to read the story behind it, that is fine, I will not be offended. Download it here.

For weeks I have been trying to get this out of the door. Ever since Secure Score came out, I wondered how to make the most of your security on Office 365 and get that number as high as possible. Even though Secure Score does a really good job in trying to explaining the What and the How, it lacked a bit the Why behind it in my opinion. That is what I tried to do, I use this document on my own tenant and it did help me increasing security and getting it all under control. I hope it does the same for you.

Feedback is always welcome, positive as negative. This is a learning path for me as well.

Download it here.

[New video] Help your end-users be aware of phishing attack by customizing their login experience in Office 365 and Azure.

[New video] Help your end-users be aware of phishing attack by customizing your login experience in Office 365 and Azure. Use the company branding functionality to customize your login page. #SecurityMatters


Azure Active Directory and Conditional Access – MFA

What if you don’t want multi-factor authentication to be an on/off switch? What would you say if you could activate MFA based on criteria like Risky Sign-ins, Domain Join Status and so much more. Be smart with your MFA. Combine Conditional Access of Azure Active Directory with MFA and be amazed by the potential … 

Protect yourself again phishing attacks in Office 365 by using Company Branding

A quick tip

If you want to avoid being the victim of phishing this will help. Phishing attacks will lead you to a fake login page where they will ask for a username and password, hoping that the end-user will not see the difference between the real login page and the fake page. With Azure Active Directory you can change the login page for Office 365 so it contains your logo, a tagline, and some basic company information. Phishing attackers in most cases won’t go through the trouble to build a custom login page. If you end-user see that the login page is not your custom designed login page, they will know it a fake one. Since AAD Company branding is a part of the Office 365 license, this is available to you for free.

Company branding happens in the Azure portal. So we need to authenticate with our Office 365 credentials at Proceed to Azure Active Directory and you should see your Office 365 Directory and the following option Company branding.



Change your company branding to your own design. In my case, I changed the Californian Highway with my own preferred image, added a logo and change the sign in text.


When the configuration is changed when you fill in a username of your Office 365, the design will change from the default Office 365 login experience to your customized one. This will be the case for each application that uses your Azure Active Directory login page. So if you end-user are the subject of a phishing attack they should see that the login experience doesn’t change based on their username and that should help them identify that something is wrong with the page.

PowerShell Automation: Save Password in a file for further use.

When you want to use PowerShell with a service, in most cases you will need to authenticate to that service. If you are looking to automate, trivial task, you will need some kind of mechanism to load your credentials from a separate, secure location so you don’t need to be available when the script runs. Of course you can save the password in the file but that isn’t really secure.

Part 1: Retrieve password from the user and save it into a file

$username = “”

$secureString = read-host “Please provide password for Office 365” | ConvertTo-SecureString -AsPlainText -Force

$secureStringText = $secureString | ConvertFrom-SecureString

Set-Content “c:\scripts\passwordtest.txt” $secureStringText


Part 2: Load from a file and connect to the service. In this case the service is Office 365.

$secureString = Get-Content “C:\scripts\passwordtest.txt” | ConvertTo-SecureString

$myCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $secureString

Connect-MsolService -Credential $myCredentials

Data Loss Prevention in SharePoint Online based on metadata

When we look at Data Loss Prevention in Office 365, either in Exchange Online, or in SharePoint Online (included here is OneDrive), people will often think it is only to be used for sensitive data. And in their mind, sensitive data is personally identifiable information, financial information like credit card number or even medical information. However, sensitive data can be so much more. Let’s take SonyGate a few years ago. I bet that their definition of sensitive information goes far beyond that.

Microsoft has done a stellar job in extending their definition of sensitive information with everything they can identify for a large number of people. But what about corporate sensitive data? Legal documents, contracts? How about we start protecting those? And that is exactly what we are going to do in this post. We are going to create a DLP policy to protect contracts. In SharePoint Online there are few ways you can identify a document to be a contract. You can use content types, metadata, etc. I am a huge fan of content types so I am going to use that.

Ok, I am not going to explain how you add a content type to a document library. If you need help for that, there are tons of good videos and blog posts that will explain it in detail. So fast forward to the part where I added the content type to a document library and I upload a document.






Ok. DLP in SharePoint Online can use a search query to activate the DLP rule. Few opening remarks with this though, adding a search query to a DLP rule can’t be done by the user interface. You need to use PowerShell for this. Additionally, any changes you want to make to the DLP rules can’t be done through the user interface. Again, this needs to be done through PowerShell. Before we start however we need to make sure we have a search query we can use in the rules. To do this I am going to create a new mapping between a managed property and a crawled property in SharePoint Online Search. Go to Office 365 > Admin > SharePoint Online > Search > Manage Search Schema. I mapped ows_ContentType to RefinableString01 and added an alias ContentTypeAlias. Trigger a crawl or be patient until the crawl has picked up your document and test it out through a search in SharePoint Online.

SearchTerm: ContentTypeAlias:Contract

This search shows me all the documents with the content type contract.







Success. Now I can create my DLP policy. Like I said before since this functionality is not available through the user interface you need to feel comfortable using PowerShell and understand how a DLP policy and rule is created.

Step 1: Connect to Security and Compliance with PowerShell

$myCredentials = Get-Credential

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $myCredentials -Authentication Basic -AllowRedirection

Import-PSSession $Session

Step 2: Create a DLP Policy. This policy will only apply to SharePoint and OneDrive. If you want to include Exchange you can do that by adding -ExchangeLocation parameter. Check the documentation for more details.

New-DlpCompliancePolicy -Name Contract_policy -SharePointLocation All -OneDriveLocation All -Mode Enable

Step 3: Add a DLP rule to the policy. DLP rules are the brains of the organization so you want to stop and think what you are trying to achieve. DLP is an ideal way to educate people about data security. DLP rules allow you the present a policy tip to the end user explaining what he is trying to do might be in violation of a specific policy. DLP rules should protect data, but there might be a reason why you need to “break” the rule. People should be able to do this, but they need to provide a justification. The last configuration I want to set, I want this rule to apply to sharing with external people. I have no problem with contracts being shared internally. So when you are done, this is what you get. And of course, we use our search term and the content identification to be protected.

New-DlpComplianceRule -Name Contract_content -Policy Contract_policy -AccessScope NotInOrganization -BlockAccess $true -BlockAccessScope PerUser -ContentPropertyContainsWords “ContentTypeAlias:Contract” -Disabled $false -NotifyAllowOverride “WithJustification” -NotifyPolicyTipCustomText “This is a Contoso Contract! Treat as Confidential” -NotifyUser “Owner”

One the DLP is activated and had time to put its rules on the document, this is what the end-user will see when he tries to share a document with an external user that has the content type contract.




Create Helpdesk Team and add all licensed users as members through PowerShell

In this post, we have a small tip for people who are using teams and want to create a helpdesk team and add all licenses users in Office 365 as members.

First, you need to install the Microsoft Teams PowerShell module.

Install-Module MicrosoftTeams -Scope CurrentUser

Once that is done, we can start creating the script to run.

We need to connect to Office 365 and Microsoft Teams. In most cases, these are the same credentials. You can collect them through a login screen or you can store it somewhere in a location and let Powershell retrieve it. That is what I am going to do.

$username = ""

$secureString = Get-Content "C:\scripts\password.txt" | ConvertTo-SecureString
$myCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $secureString

Connect-MicrosoftTeams -Credential $myCredentials
Connect-MsolService -Credential $myCredentials

Now we can create the team. We want to build in some safety measure to check that the team exists or not.

$group = Get-Team | ? { $_.DisplayName -like "HelpDesk"}
if (!$group)
$group = New-Team -DisplayName "HelpDesk" -AccessType Private
write-host "Group already HelpDesk exists"

Next step is to retrieve the licensed users

$users = Get-MsolUser -All| ? {$_.IsLicensed -eq $true}</blockquote>
Now we are going to use the $users collection to add them to the team
<blockquote>foreach ($user in $users)
if (Get-TeamUser -GroupId $group.GroupId | ? {$_.User -eq $user.UserPrincipalName})
write-host "$($user.UserPrincipalName) user already exists"
Add-TeamUser -GroupId $group.GroupId -User $user.UserPrincipalName -Verbose -Role Member

Run it and admire your work. One thing to remember, not all changes are going to be immediately visible in your Team application. According to documentation, there can be a delay up to 1 hour (at least at the time this blog post was written)

Cloud Apps Security, Protect your files in a Secure MultiCloud World

After the rise of hybrid cloud within a single vendor, we have reached the next step of complexity with multicloud. It is not realistic to believe in a single vendor cloud world. There is going to be a continuous battle between cloud service for new customers, convert existing customers to their platform and in some ways, integration needs to happen between different cloud services. Microsoft knows that too. Look at what they are trying to do around the integration of DropBox and Box in Microsoft Teams, around Azure Information Protection to on-premises systems and their plans to extend AIP  or rather MIP towards non-Microsoft platforms.

Cloud Apps Security (CAS)  is another example that shows that Microsoft understands that it can hope for Cloud Service Domination but reality might be different or the timeframe for that domination might be a bit longer than anticipated. So what is this CAS thing? Well, look at CAS as a centralized dashboard you can use to identify, control, protect and do threat analysis of your cloud services. Supported at this time are Box, DropBox, GoogleDrive, OneDrive for Business and SharePoint Online. CAS can be found as a separate entity in your Office 365 Admin, that is, if you have an existing license for it. You can trial it for 30 days.

A limitation I want to start with from the beginning is the fact that CAS only supports Enterprise versions of the existing cloud services. It will not support personal Dropbox, Box or OneDrive. So this is something to keep in mind.

As it is is today, CAS can identify which cloud services are being used based on traffic logs. You upload your traffic logs from your local connection and CAS will identify any cloud services are being used as Shadow IT. Since this is based on traffic logs, you need a device that will capture those. If you are a fully remote employee, whose traffic is not going through a BlueCoat or SonicWall or other appliances, the discovery can only do so much.

The second functionality is the investigation. Investigation allows you to do deep dive analysis of what is going on your cloud services. It can retrieve everything from an activity log, user interactions, and any file investigations. Since this was a test for me, identifying what the potential is of CAS so I really focused on files and the ability to detect and protect the content of files. I created a policy (which I will discuss in detail later in this post) to detect and protect files containing PII like an SSN. When a document triggers that policy, this will be reported in the investigation option under files.

Screen Shot 2018-02-12 at 10.32.03 AM

The third part of CAS is control. It is in this section where you are going to define policies to protect your content in your files. We are going to create a policy to protect all files in my Box, GoogleDrive, OneDrive for Business and SharePoint online when they contain PII information like SSN. There are multiple ways to create policies, start from scratch, start from a template, etc. I always try to go for the minimal path of resistance, so not a surprise here, I will start with a template.

Screen Shot 2018-02-12 at 10.50.41 AM.png

Now, what was striking to me is that it said built-in-DLP engine. So that means (at least for now) CAS is not using the same DLP Engine as Office 365. It uses its own DLP engine to identify certain sensitive types of data. Later on, you will see that the options for specific PII are very limited in comparison with what Office 365 already has built-in. To create the policy based on a template, just click the + attached to it.

A policy has a number of settings you can choose to define or not. Some are mandatory, some are optional, they define the reach and actions of your policy. In my policy, I want to protect my SSN numbers. In the first section, I can define the severity of the policy, any potential filters, pretty much the reach of your policy. In my policy where I want to protect everything, I don’t have to define any filters.

Screen Shot 2018-02-12 at 10.59.09 AM

In the second section, I am going to define what exactly I am looking for. I want to identify files that contain US: PII: Social Security Number. Those are loaded through a preset in the setting, you can define your own regular expression if you want to look for something that isn’t covered. You also need to define where to look exactly, you can let the engine look in the content, metadata, and filename. Last part is to define how many occurrences will trigger the policy.

Screen Shot 2018-02-12 at 11.25.33 AM

Next part is to set up how your alerts need to be generated. You can create an alert for each matching file, send an email or even a text message, like in my example.

Screen Shot 2018-02-12 at 11.25.57 AM.png

And now comes the cool part, in my opinion, the governance rules. If a file is matched against the policy what needs to happen. These actions as you can see in the next image are defined per cloud service. Some cloud services will support different governance actions. They can go from removing the shared link, restrict permissions and my favorite, put the file in quarantine. For the Box environment, I choose the user quarantine while for OneDrive for Business and SharePoint Online are going to go for an admin quarantine.

Screen Shot 2018-02-12 at 11.26.05 AM

Screen Shot 2018-02-12 at 11.26.13 AM

Let’s start by explaining what quarantine means. When a document is put quarantine it is replaced by a text file like e.g. TEST SSN copy.docx.QUARANTINE.txt and when you open the document this is shown.

Screen Shot 2018-02-12 at 6.38.46 PM

Depending on the fact if the quarantine is admin or user based, the quarantine folder will be either be created in a centralized location or within in the user’s environment. If it is a user based, the end-user will still have the option to go into the quarantine folder and get the document. In an admin based quarantine, the document is stored in a centralized location and based on the permissions of that location the user still has access or not.

When an alert is created, it will be part of the alert section in CAS. At the same time, if you defined for an email or text message to be sent, that will happen as well.

Screen Shot 2018-02-12 at 6.45.18 PM

When you go to the CAS dashboard, you will see the alert based on your configuration.

Screen Shot 2018-02-12 at 6.44.17 PM.png

Alerts can be left open, they also can be dismissed and resolved. This way you can keep track of which alerts you still have to act on and which ones are resolved. When we go more into detail of a single alert you will see that it will tell you all the information you need. It also allows you to perform certain actions on it. E.g. if this was a false positive, you can use the restore from admin quarantine to put the document back to its original location.

Screen Shot 2018-02-12 at 6.44.47 PM

So, this is only specific use case. Even with this basic version of CAS, a lot of possibilities are available. There are however a number of limitations that CAS has, that are pretty significant.

  • Only Enterprise versions of Cloud Services are covered in CAS.
  • Only Cloud Services are covered after all this is still a hybrid world, so what do we do with legacy ECMS like FileNet, OpenText, etc.
  • Very limited sensitive data classification, which is weird to me, since Microsoft has done such a great job in other services in Office 365, why this separate engine

I am looking forward to seeing more of this in the next few months. Keep posted…