Enable default sensitivity labels in SharePoint Online


General Introduction

SharePoint can automatically apply sensitivity labels to a document library. New documents, both created online or uploaded and existing ones (when they are edited), will get the sensitivity label you chose.

If a document label gets manually modified, SharePoint won’t overwrite the label. This isn’t usually an issue because only a few selected number of employees should have the permissions to declassify a document.

This automation supports the following file formats:

  • Word: .docx, .docm
  • Excel: .xlsx, .xlsm, .xlsb
  • PowerPoint: .pptx, .ppsx
  • PDF (Preview)

Whilst the support for PDFs is still in preview, I still have yet to have issues with it.

This script was written because I found the steps to enable this feature a bit confusing, and so I wanted to simplify the process with a simple automation.

Before running the script, create and publish your sensitivity labels. You have to publish the label to the user setting the default sensitivity label.

After running the script, go into the labels and modify the scope to include groups and sites. You’ll have to wait a bit between running the PowerShell script and enabling groups and sites, as it’s greyed out by default.

After you have enabled groups & sites, you’ll have to wait for the setting to label a SharePoint library to show up.

To set the default label, go under SharePoint Admin Center, then Sites, Active Sites, and click on the site you wish to apply the sensitivity label to. Under Settings, you’ll find a Sensitivity label dropdown.


Limitations of default sensitivity lables


The script

I’d suggest updating your SharePoint Online Management Shell before running this script. You can download the new version here:

https://www.microsoft.com/en-us/download/details.aspx?id=35588

Modify the two variables before running the script.

# Define the variables for your enviroment. The first one is the link to your SharePoint Admin Portal. The second one is your administrator account User Principal Name

$SPAdminLink = "https://yourtenant-admin.sharepoint.com"
$AdminUPN = "youradminUPN@contoso.com"

# Connect to SPO. Replace the link with your SharePoint Admin portal

Connect-SPOService -Url $SPAdminLink

# Enable AIP Integration

Set-SPOTenant -EnableAIPIntegration $true
(Get-SPOTenant).EnableAIPIntegration

# Enable support for PDFs. Update SP Online Module if this fails. The link is https://www.microsoft.com/en-us/download/details.aspx?id=35588

Set-SPOTenant -EnableSensitivityLabelforPDF $true
(Get-SPOTenant).EnableSensitivityLabelforPDF

# Connect to AAD and enable support for labels in groups. Source: https://learn.microsoft.com/en-us/microsoft-365/compliance/sensitivity-labels-teams-groups-sites?view=o365-worldwide

Install-Module AzureADPreview
AzureADPreview\Connect-AzureAD

$grpUnifiedSetting = (Get-AzureADDirectorySetting | where -Property DisplayName -Value "Group.Unified" -EQ)
$Setting = $grpUnifiedSetting

# Check if EnableMIPLabels is enabled. If nothing is displayed then you have no group settings. We'll enable it. 

$grpUnifiedSetting.Values

# Enable the feature. If it fails check out this guide: https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/groups-settings-cmdlets#create-settings-at-the-directory-level

$Setting["EnableMIPLabels"] = "True"

# Check that now it's enabled. If it's enabled you'll get
#
#Name                            Value
#----                            -----
#EnableMIPLabels                 True

$Setting.Values                                                                                                                                                                                                    

# Save 

Set-AzureADDirectorySetting -Id $grpUnifiedSetting.Id -DirectorySetting $Setting

# Now we'll import ExchangeOnlineManagement and then connect the Compliance Powershell to sync the labels

Import-Module ExchangeOnlineManagement
Connect-IPPSSession -UserPrincipalName $AdminUPN
Execute-AzureAdLabelSync


Sources:

https://learn.microsoft.com/en-us/microsoft-365/compliance/sensitivity-labels-sharepoint-default-label?view=o365-worldwide

https://learn.microsoft.com/en-us/microsoft-365/compliance/sensitivity-labels-teams-groups-sites?view=o365-worldwide

https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/groups-assign-sensitivity-labels

https://learn.microsoft.com/en-us/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files?view=o365-worldwide

10 tips to improve your administrative accounts posture in Azure AD


General Introduction

As I speak to more and more customers about the matter, I notice that a lot of companies have a questionable security posture regarding their administrative accounts. For example, many admins are using their “daily-runner” account as privileged administrators for their tenants, or synchronizing their domain admins to privileged roles in Azure AD. In general, a lot of admin accounts aren’t getting the care they deserve.

Losing privileged access is a big deal and it’s happening more and more often. Clearly, attackers love targeting privileged accounts because they give them quick and broad access to a company’s important assets, leaving a lot of defences behind.

I decided to write this article to highlight some of the controls that should be implemented in our tenants to improve our admin accounts posture, as privileged access management should be one of our top security priorities. These points have been aggregated after a lot of discussions with colleagues and experts on the topic and with the help of best practices from Microsoft Docs.


The 10 tips list

As a best practice, administrator accounts should be: 

  1. Separate from your daily-runner account. Collaboration tasks should not be done from the administrative accounts. While it’s of course not convenient, admins should get used to handling multiple accounts for different permission levels.
  2. Cloud-only. Your Azure AD administrator accounts should be different to your on-premises admins, and should not be synchronized from the on-premises Active Directory. This is because if one’s identity gets breached, the attackers would have easy access to both Azure AD and AD.
  3. Mailbox-less. The easy way to implement this is by not assigning admins licenses. You should enable a forward from your admin account to your daily driver account, or a dedicated mailbox/distribution list assigned to an unprivileged user. 
  4. Using phishing-resistant authentication methods. FIDO2 keys should be your primary way of accessing your admin accounts. If FIDO2 keys or similar methods are unavailable to you, you should have at least MFA active on your account with number matching and additional details active. Ideally, you should also restrict access to your resources to only allow access from known devices.
  5. Reviewed periodically. Periodically analyse the list of admins, and remove excessive permissions. There are a lot of cool tools that can help you out with this, or you can script your own.
    Microsoft suggests analysing these roles first, then moving to the other administrative accounts: Global Administrator, Privileged Role Administrator (they are a click away from being Global Admins), Exchange Administrator, and SharePoint Administrator. Remove guest admins where applicable.
  6. Protected by Identity Protection. Identity Protection automatically scans your sign-ins and blocks the user if anything strange is going on. You can also configure it to force the user to do a self-service password reset.
  7. PIM-enabled. You should have administrative privileges only when you require them. Having admin privileges active on an account 24/7 without a specific reason is not the best idea. Moreover, whenever you enable your PIM roles, you get an email, to keep everything under control.
  8. Backed up by one or two emergency accounts. If bad things happen, you should still be able to access your tenant. Emergency access administrators help you with that. You should also consider activating a rule to alert you when this admin gets used. Here is a cool guide to create passwordless emergency admins with FIDO2 Keys: https://janbakker.tech/break-glass-accounts-and-azure-ad-security-defaults/
  9. Logged constantly. Configure logging for your tenant by exporting the Azure AD logs to a Log Analytics workspace (https://azvise.com/2023/06/21/export-azure-ad-entra-logs/). Alerts should be configured for risky actions (like modifying a conditional access policy). Also, check if you have enabled the Unified Audit Logs: https://azvise.com/2021/10/26/office-365-enable-unified-audit-logs/
  10. Protected with Conditional Access Policies. This is a very broad topic, but make sure that at least the following apply. Those policies can be created quickly using Conditional Access policies templates: Require phishing-resistant multifactor authentication for admins, Securing security info registration, block legacy authentication, require multifactor authentication for Azure management, Require compliant or hybrid Azure AD joined device for admins, Block access for unknown or unsupported device platform, No persistent browser session. Of course, before activating this policies, be really careful to test things out and exclude the emergency account(s).

Additional points:

  • Use precise Administrative roles. Of course, using highly privileged accounts it’s convenient, as you have only to activate one role to manage everything. But if you assign people the correct permissions they need for their daily job, a lot of headaches can be prevented. Check out this documentation page to ease the pain of finding the right role to assign:
    https://learn.microsoft.com/en-us/azure/active-directory/roles/delegate-by-task
  • Consider Privileged Access Workstations. Having PAWs for Admin roles can help a lot with your security posture. PAWs can be configured on Azure AD with device filtering rules in Conditional Access Policies. For example the CAP may require: When all admins, except for the emergency access administrator, access all apps, block access unless they are using specified devices, filtered by device ID.
    These PAWs should be AAD joined, and are usually for Global Admins and Privileged Role Administrators. Also, having Bitlocker on at least this machines is a must.
    Spoofing device IDs with Powershell is sadly possible at the moment, but it’s kinda hard and not one of the first things that attackers will do. As always, a lot of this depends on your security risk acceptance level.
    If you want to drill down on PAWs, this article might be useful: https://learn.microsoft.com/en-us/security/privileged-access-workstations/privileged-access-devices
  • If you have an on-premises AD, you should really look into improving your AD security, as your AAD security and your AD security are tightly correlated. A tiering model for Active Directory is really useful to better manage your forests, and implementing Defender for Identity gives you a whole new level of analysis and reaction on what’s going on. This won’t be discussed here, but there are plenty of resources to get started with this. Also, again, don’t sync your on-prem administrators to Azure AD. You should have some level of filtering from on-prem to Azure AD, such as filtering by OU or by AD attributes.
  • Also not discussed here, as Azure permissions are a whole topic by themselves, but you should really be analyzing Azure privileged permissions and keeping everything under control.


Link to Microsoft docs, and additional reads:

Securing privileged access

Ensure separate user accounts and mail forwarding for Global Administrator accounts

Enterprise access model

Token Protection

Scale AKS HCI control plane and worker nodes



  1. Notes
  2. Scale the Control Plane
  3. Scale worker nodes

In Azure Kubernetes Service (AKS) on Azure Stack HCI, you can increase the resources available to your node pool by changing the size of virtual machines in a node pool or expanding the node count. The node count can also be increased with autoscaling methods.

The worker nodes can be scaled using the command Set-AksHciNodePool, while the Set-AksHciCluster scales the control plane.

I’ll be going over scaling both using PowerShell in the following guide. You’ll need to open a PowerShell session on one of the Azure Stack HCI nodes to follow along. Replace the parameter values as needed. 

Notes

  • As of January 2023, the scaling of the management cluster (the one created by AKS HCI automatically) is currently not supported.
  • At the time of writing, the “-vmsize” argument used with Set-AksHciNodePool is not documented in the command docs (Set-AksHciNodePool | Microsoft Docs) but is only referenced in this article: Scale up a worker node | AKS HCI Docs



Scale the Control Plane

Now we’ll scale up the current cluster. You’ll see the control plane VM size under ControlPlaneVmSize.

Get-AksHciCluster -name akshci01

Status                : {ProvisioningState, Details}
ProvisioningState     : Deployed
KubernetesVersion     : v1.23.8
PackageVersion        : v1.23.8
NodePools             : linuxnodepool
WindowsNodeCount      : 0
LinuxNodeCount        : 4
ControlPlaneNodeCount : 1
ControlPlaneVmSize    : Standard_D2s_v3
AutoScalerEnabled     : False
AutoScalerProfile     :
LoadBalancer          : {VMSize, Count, Sku}
Name                  : akshci01

You’ll only be allowed to scale up the control plane to the available VM sizes. To get which sizes are availabe, use Get-AksHciVmSize.

Get-AksHciVmSize

VmSize CPU MemoryGB
------ --- --------
Default 4 4
Standard_A2_v2 2 4
Standard_A4_v2 4 8
Standard_D2s_v3 2 8
Standard_D4s_v3 4 16
Standard_D8s_v3 8 32
Standard_D16s_v3 16 64
Standard_D32s_v3 32 128
Standard_DS2_v2 2 7
Standard_DS3_v2 2 14
Standard_DS4_v2 8 28
Standard_DS5_v2 16 56
Standard_DS13_v2 8 56
Standard_K8S_v1 4 2
Standard_K8S2_v1 2 2
Standard_K8S3_v1 4 6

In this example we’ll scale up to a D4s_v3.

Set-AksHciCluster -name akshci01 -controlPlaneVmSize Standard_D4s_v3

Status                : {ProvisioningState, Details}
ProvisioningState     : Deployed
KubernetesVersion     : v1.23.8
PackageVersion        : v1.23.8
NodePools             : linuxnodepool
WindowsNodeCount      : 0
LinuxNodeCount        : 4
ControlPlaneNodeCount : 1
ControlPlaneVmSize    : Standard_D4s_v3
AutoScalerEnabled     : False
AutoScalerProfile     :
LoadBalancer          : {VMSize, Count, Sku}
Name                  : akshci01

Now that we have scaled up the control plane, we can scale the control plane node count. The default is 1. If you scale up the control plane, it will become highly available and will not accept any scale down back to 1 node⚠️

Set-AksHciCluster -name akshci01 -controlPlaneNodeCount 3

Status                : {ProvisioningState, Details}
ProvisioningState     : Deployed
KubernetesVersion     : v1.23.8
PackageVersion        : v1.23.8
NodePools             : linuxnodepool
WindowsNodeCount      : 0
LinuxNodeCount        : 4
ControlPlaneNodeCount : 3
ControlPlaneVmSize    : Standard_D4s_v3
AutoScalerEnabled     : False
AutoScalerProfile     :
LoadBalancer          : {VMSize, Count, Sku}
Name                  : akshci01



Scale worker nodes

Now we’ll do the same thing we did for the control plane with the worker nodes. Here we’ll get the default VM size for the cluster.

Get-AksHciNodePool -clusterName $aksclustername

Status : {Phase, Details}
ClusterName : akshci01
NodePoolName : linuxnodepool
Version : v1.23.8
OsType : Linux
NodeCount : 2
VmSize : Standard_K8S3_v1
Phase : Deployed
AutoScalerEnabled : False

You’ll only be allowed to scale up the worker nodes to the available VM sizes. To get which sizes are availabe, use Get-AksHciVmSize.

Get-AksHciVmSize

VmSize CPU MemoryGB
------ --- --------
Default 4 4
Standard_A2_v2 2 4
Standard_A4_v2 4 8
Standard_D2s_v3 2 8
Standard_D4s_v3 4 16
Standard_D8s_v3 8 32
Standard_D16s_v3 16 64
Standard_D32s_v3 32 128
Standard_DS2_v2 2 7
Standard_DS3_v2 2 14
Standard_DS4_v2 8 28
Standard_DS5_v2 16 56
Standard_DS13_v2 8 56
Standard_K8S_v1 4 2
Standard_K8S2_v1 2 2
Standard_K8S3_v1 4 6

Now that we know which sizes are supported, we can scale up the cluster nodes. All preexistent nodes will be scaled up ⚠️

Set-AksHciNodePool -ClusterName "akshci01" -name "linuxnodepool" -vmsize "Standard_DS13_v2"

Status : {Phase, Details}
ClusterName : akshci01
NodePoolName : linuxnodepool
Version : v1.23.8
OsType : Linux
NodeCount : 2
VmSize : Standard_DS13_v2
Phase : Deployed
AutoScalerEnabled : False

Now that we have scaled up, we can scale the workload node count. The current node count depends on what you have set during setup.

Set-AksHciNodePool -clusterName "akshci01" -name linuxnodepool -count 4


Status            : {Phase, Details}
ClusterName       : akshci01
NodePoolName      : linuxnodepool
Version           : v1.23.8
OsType            : Linux
NodeCount         : 4
VmSize            : Standard_DS13_v2
Phase             : Deployed
AutoScalerEnabled : False

What’s SMS Authentication and how to enable it in Azure AD


What’s Text Message Authentication

SMS-based authentication allows users to log in without needing to remember their username and password. After enabling the feature for an account, users can enter their phone number at the login prompt instead of their username. They will then receive an authentication code via text message that they can use to complete the login. 

This service is often mistaken for SMS-based Multi-factor Authentication, but they are not the same.

This authentication method makes it easier for frontline workers to access applications and services. It’s not recommended to enable this feature for users who could use other passwordless methods or a combination of credentials + MFA. It’s also important to note that the desktop Office apps do not support SMS-based auth. Therefore, you can only use the web app version of the apps and only by logging in via office.com. You also cannot use the mobile version of the apps, except for Teams, Company Portal and Microsoft Azure.

If you decide to enable the feature, you should consider limiting and standardizing the frontline worker’s permissions to what’s necessary.

If you are curious why you should prioritize other methods over phone-based auth, consider reading this always relevant article by Alex Weinert:

It’s Time to Hang Up on Phone Transports for Authentication – Microsoft Community Hub


Critical Considerations

  • SMS-based authentication isn’t compatible with Azure Multifactor Authentication.
  • The only mobile apps that support SMS-auth are Teams, Company portal and Azure.
  • The users will need to use the web version of the Office apps and log in via office.com.
  • You’ll have to set up phone numbers for each account before the users can sign in.
  • A phone number can only be associated with one user.
  • If you have alternatives to phone-based auth methods, use them.


General Requirements


PERMISSIONS:

  • Being a Global Admin for the tenant

LICENCES:

  • Each user enabled for the feature must have one of the following:
    • Microsoft 365 F1 or F3
    • Azure Active Directory Premium P1 or P2
    • Enterprise Mobility + Security (EMS) E3 or E5 or Microsoft 365 E3 or E5
    • Office 365 F3


Tips

  • You can assign phone numbers to users using PowerShell for an easier setup experience.


How to enable the feature

  • Create a group with the users that’ll need to authenticate using SMS.
  • Open Authentication Methods | Azure AD
  • Click on SMS (Preview). The feature is not in preview anymore, even if the portal states so at the moment of writing this guide.
  • Click on “Yes” under “Enable”, then “Select groups”, and select the group you created in the first step. Complete the step by clicking “Select” and “Save”.
  • To set a phone number, go into All Users | Azure AD, then select a member of the group you created in the first step.
  • Go into “Authentication methods”, then click “Add authentication method”. From there, select “Phone number” and insert the phone number the user will use to sign in, then click “Add”.
  • You can also add an authentication method via PowerShell:
# Replace the variables with the user you wish to add the auth method to and phone number you wish to assign

$User = "user@example.com"
$PhoneNumber = "+1 111111111"

Install-module Microsoft.Graph.Identity.Signins
Connect-MgGraph -Scopes UserAuthenticationMethod.ReadWrite.All
Select-MgProfile -Name beta

New-MgUserAuthenticationPhoneMethod -UserId $User -phoneType "mobile" -phoneNumber $PhoneNumber

# Get the phone number of the user

Get-MgUserAuthenticationPhoneMethod -UserId $User

If you need to script this for multiple users, you can refer to the code below.

This script assumes you created a CSV file in “C:\” named contacts.csv, and that the CSV file has a column named UserName and a column named PhoneNumber. If your CSV file has different column names, you will need to update the script accordingly.

# Install the modules and login to Graph

Install-module Microsoft.Graph.Identity.Signins
Connect-MgGraph -Scopes UserAuthenticationMethod.ReadWrite.All
Select-MgProfile -Name beta

# Import the CSV file containing names and phone numbers

$contacts = Import-Csv -Path "C:\contacts.csv"

# Loop through each user and add their phone number for authentication
# If you changed the column names, replace these placeholders with the actual column names from the CSV file


foreach ($contact in $contacts)
{
    $User = $contact.UserName
    $PhoneNumber = $contact.PhoneNumber
    New-MgUserAuthenticationPhoneMethod -UserId $User -phoneType "mobile" -phoneNumber $PhoneNumber
}



To learn more, refer to the following links:

SMS-based Authentication | Microsoft Docs

SMS-based Authentication – Supported apps | Microsoft Docs

Get all users of an Azure AD Group and add them to another one – Powershell

The following script will get all the members of an Azure AD group and add them to another group. You’ll just need to know the name of the two groups to make it work.

In the code shown below, the source group will be called Group1Name and the destination one Group2Name.

# Replace Group1Name with the name of your source group and Group2Name with the name of the destination one. Everything else will be done automatically

$Group1 = "Group1Name"
$Group2 = "Group2Name"


$group1ObjectID = Get-AzureADGroup -Filter "Displayname eq '$group1'" | Select objectid -ExpandProperty ObjectID
$group2ObjectID = Get-AzureADGroup -Filter "Displayname eq '$group2'" | Select objectid -ExpandProperty ObjectID

$membersGroup1 = Get-AzureADGroupMember -ObjectId $group1ObjectID -All $true

foreach($member in $membersGroup1)
{
    $currentuser = Get-AzureADUser -ObjectId $member.ObjectId | select objectid
    Add-AzureADGroupMember -ObjectId $group2ObjectID -RefObjectId $currentuser.objectid

}
Get-AzureADGroupMember -ObjectId $group2ObjectID -All $true

Disconnect a user session in Azure Virtual Desktop (AVD) – PowerShell

Prerequisites: The Microsoft.RDInfra.RDPowerShell module, the Az PS module

First, install the RDInfra module:

Install-Module -Name Microsoft.RDInfra.RDPowerShell; Import-Module -Name Microsoft.RDInfra.RDPowerShell

Then proceed by installing the Az module and logging in:

Connect-AzAccount

Once you are logged in you can run the following script to disconnect a specific user session:

Get-RdsUserSession -TenantName "tenantname.onmicrosoft.com" -HostPoolName "HostPoolName" | where { $_.UserPrincipalName -eq "azvise\demouser" } | Invoke-RdsUserSessionLogoff -NoUserPrompt