Running Exchange Online Historical Message Traces for Sets of Mailboxes

A question was asked about the best way to find out if shared mailboxes received email from certain domains over the past 60 days. Exchange Online historical message traces can extract trace data to allow us to check, but the process of running the message trace and then analyzing the data is just a little disconnected.

Reporting Distribution List Membership with the Microsoft Graph PowerShell SDK

Microsoft will deprecate the Azure AD and MSOL PowerShell modules in June 2023. It’s time to convert scripts that use cmdlets from these modules and the Microsoft Graph PowerShell SDK is probably the best answer. This article explains how to generate a report of Exchange Online distribution list memberships, a task often handled in the past with Azure AD cmdlets.

Adding New Azure AD Users to Groups Automatically

Several methods exist to add new user accounts to groups automatically. Dynamic group membership is an obvious option, but other choices exist, including org-wide teams (if your organization is under 10,000 accounts) and using PowerShell to manage the automatic addition of new members to a standard distribution list or Microsoft 365 group. This article examines the various methods. Once you understand what’s possible, you can make the right choice.

Using PowerShell to Manage Azure AD Custom Security Attributes

Azure AD custom security attributes can mark user and service principal objects for special processing, which is how the app filter for conditional access policies works. It’s nice to be able to interact with data through PowerShell and the Microsoft Graph PowerShell SDK cmdlets support setting, updating, and retrieval of Azure AD custom security attributes. Everything works, but it’s a pity that it’s a little clunky.

Creating a Teams Directory with PowerShell

Microsoft Teams doesn’t come with a Teams Directory, so it’s hard to know if a suitable team already exists when people ask for a new team. This fact contributions to teams sprawl where multiple teams exist to serve the same purpose. Teams sprawl creates an obstacle to effective collaboration and runs the danger that some important information is tucked away inside teams that no one ever goes near. Creating a Teams Directory helps team owners and users know what teams already exist inside a tenant. It’s an idea that just makes sense.

Use the Audit Log to Monitor Membership Changes in Selected Microsoft 365 Groups

A reader asks how to monitor membership changes for some specific high-profile groups. You can buy a commercial product to do the job or use PowerShell to exploit the information held in the Office 365 audit log. A combination of a custom attribute assigned to the sensitive groups and an audit log search does the job.

Upgrade of Teams Policy Cmdlets Enables Use in Azure Automation

This article explains how to make Teams policy assignments using an Azure Automation runbook and some of the modernized cmdlets available in the Teams PowerShell module. Not everything worked as smoothly as we’d like, but like most PowerShell scenarios, there’s usually a workaround available to get the job done. It just needs to be found.

Report SSPR Status for Azure AD Accounts

In most situations, it’s a good idea to enable Azure AD accounts for SSPR (self-service password reset) to avoid the need for administrators to update user accounts when things go wrong. This article explains how to report accounts that are not yet set up to use SSPR. It’s a check that should happen regularly, perhaps with the aid of Azure Automation.

Assigning Permissions to Azure AD Apps to Use the Microsoft Teams PowerShell Module

Before an app or an Azure Automation account can use the Teams PowerShell cmdlets in a script or runbook, it must have the permission to act as an administrator. In this article, we cover how to assign the necessary role to a service principal.

Reporting Who Made License Assignments

This article explains how to use PowerShell and the Office 365 audit log to report Azure AD license assignments. The output isn’t pretty, but it works. The code works by finding two different audit events for each license assignment and combining information from both events to create a view of what happened. It’s rough and ready and can be improved, but the principal is proven and that’s what I set out to do.

Making Sure Apps Can Run Exchange Online Management Cmdlets

This article describes how to use the Exchange.ManageAsApp permission to allow Azure AD apps to run Exchange Online PowerShell cmdlets. You can do this in the Azure AD admin center for registered apps, but when the time comes to allow Azure Automation runbooks to sign into Exchange Online with a managed identity, you must assign the permission to the automation account with PowerShell. Easy when you know how, hard when you don’t!

Scripting Azure AD Authentication Methods

A script written by a Microsoft program manager to remove authentication methods from an Azure AD account caused me to write a script to capture all the authentication methods used in a tenant. I have other similar scripts, but this one records some additional detail for each method. And I have a moan about why the Microsoft Graph PowerShell SDK includes so many cmdlets for interacting with authentication methods. Some consolidation would be nice.

Exchange Online Archive Mailboxes Move Away from Purview Compliance Portal

Microsoft is moving the listing of archived mailboxes from the Purview Compliance portal to its natural home in the Exchange Admin Center. In this post, we look at how you can report the current status of archive mailboxes (both user and shared mailboxes) in a Microsoft 365 tenant.

Using Hidden Membership for Microsoft 365 Groups

Hidden membership is supported for Microsoft 365 Groups and distribution lists. Hidden membership means that no one except members and admins can see who’s in a group. It’s a useful feature if you don’t want people poking around to find out who’s in a group or distribution list. One thing to be aware of is that once a Microsoft 365 group has hidden membership, it has it forever. Distribution lists on the other hand can flip between hidden and visible membership.

Detect Underused Azure AD Accounts (with Expensive Licenses)

This article describes how to adapt the Microsoft 365 licensing report script to highlight Azure AD accounts that haven’t signed in for a long time. Because Microsoft charges for licenses on a monthly basis, every month that goes by racks up cost for underused accounts. The new version of the script tells you what accounts to check to help you focus on driving down licensing costs.

Teams Reactions Captured in Audit Records

Every time someone reacts to a message in a team chat or channel conversation, Teams captures an audit record and sends it to the Office 365 audit log. The Teams reactions audit records are an interesting source of information. In this article, we show how to use PowerShell to interpret the contents of the reactions, and how to use the data to find the underlying messages.

Updating Extension Attributes for Entra ID Registered Devices with the Microsoft Graph PowerShell SDK

Entra ID registered devices have 15 extension attributes that tenants can use for their own purposes. In this article, we explore how to use the Microsoft Graph PowerShell SDK to update extension attributes for registered devices, and even better, access the content in the extension attributes afterward.

Lessons Learned from Using Azure Automation with PowerShell Scripts

I’ve spent some time investigating Azure Automation PowerShell recently. In this article, I discuss three learnings that might be of interest to others. Debugging, cost, and tracking the use of Azure Automation PowerShell might not interest everyone, but they’ve certainly helped me to understand how the platform works.

Analyzing Document Label Mismatch Audit Records

Document label mismatches happen when users create, upload, or update Office documents in SharePoint sites and give the documents a higher-priority sensitivity label than the one assigned to the site. When this happens, SharePoint Online creates a DocumentSensitivityMismatchDetected audit event. Unhappily, that event doesn’t tell us who caused the mismatch, but some work with PowerShell reveals all.

Detecting Exchange Online Shared Mailboxes That Need Licenses

Exchange Online shared mailboxes only need licenses if they have an archive, exceed 50 GB in size, or are on litigation hold. The rules are there, but how many tenants check their shared mailboxes to make sure that they’re in compliance. This article explains how to use PowerShell to detect shared mailboxes that need licenses.

Report the Membership of Teams Private Channels

In this article, we explain how to create a report about the Teams private channels found in a tenant together with the members and owners of each channel. The PowerShell script is relatively straightforward and once the data is extracted from Teams, it can be sliced and diced in different ways.

Using Azure Key Vault with Microsoft 365 PowerShell

A previous article explains how to use an Azure Automation runbook to write information to a SharePoint Online site and Teams channel. At the time, I used a stored credential to authenticate and access SharePoint and Teams. Azure Key Vault offers another way to store secrets (bits of information) securely. This article explores how to store secrets in Azure Key Vault and retrieve and use the secrets in a runbook script and interactive PowerShell.

Using the Get-AssociatedTeam Cmdlet to Report Team Memberships

The Get-AssociatedTeam cmdlet is part of V4.6 of the Microsoft Teams PowerShell module. It reports the membership a user account has in teams, including where the account has direct membership of shared channels. The cmdlet makes it easy to generate a report of teams membership, and the PSWriteHTML module makes it easy to output nice PDF reports.

Populate the Membership of a Teams Shared Channel for All Users

This article explains how to populate the membership of a Teams shared channel using PowerShell. The idea is to create a shared channel that’s used for organization-wide communications, like a HR questions and answers channel. Alternatives like using a dynamic Azure AD group with a filter to find Teams users are also considered.

New Version of Microsoft 365 User Activity Report

A new version of the Microsoft 365 user activity report PowerShell script is available. This version extends the activity lookback period to 180 days, which is helpful when assessing if user accounts are active when people might be on parental leave or sabbaticals.

Using the Get-TeamAllChannel Cmdlet to Report Microsoft Teams Channels

Version 4.6 of the Microsoft Teams PowerShell module includes the Get-TeamAllChannel cmdlet. As the name implies, the cmdlet returns details of all channels in a team (regular, private, and shared). To see what it does, we wrote a script to report all the channels in teams in a tenant.

Reporting SharePoint Online External Users with PowerShell

There are many versions of PowerShell scripts to report SharePoint external users online. Most don’t handle team-connected sites, so we take the time to explain the oddities of the Get-SPOExternalUser cmdlet and create some data that we can report using the PSWriteHTML module. All in day’s work with Microsoft 365.

Use the Debug Parameter for Microsoft Graph PowerShell SDK Cmdlets to Expose Graph API Requests

Cmdlets in the Microsoft Graph PowerShell SDK module can interact with many types of Microsoft 365 data using Graph API requests. Adding the Debug parameter gives you an insight into what happens when SDK cmdlets run Graph requests. The knowledge can help you write better code and avoid mistakes, and that’s always a good thing.

How to Report Azure AD Admin Accounts Not Protected by MFA

Many example PowerShell scripts exist to report Azure AD accounts and their MFA status. Most of the scripts use the old MSOL module. Now we can use the Microsoft Graph PowerShell SDK and some Graph API requests to do the same job, This article explains how, including how to highlight unprotected Azure AD accounts that hold administrative roles.

Imminent Deprecation of Azure AD PowerShell Modules Creates Knowledge Gap in Documentation

Time is ebbing away and the date when the Azure AD PowerShell modules will start not to work is approaching. Microsoft wants customers to upgrade to the Microsoft Graph PowerShell SDK or Graph API requests. That’s fine, but a knowledge gap exists because most of the examples – including in Microsoft’s own documentation – for how to interact with Azure AD via PowerShell use the old modules. And then every other blog on the planet (with some notable exceptions) does the same. So we have work to do to bridge the knowledge gap and help people to make the transition.

How to Create Mailbox Exclusions for Microsoft 365 Sensitivity Label Policies

The GUI of the Microsoft Purview compliance center doesn’t support the exclusion of selected mailboxes when the special All target is used. However, you can use PowerShell to add mailbox exclusions to sensitivity label policies, including adding the members of a group as exclusions.

Microsoft Introduces Control Over Delegated Access to Encrypted Email

Microsoft is introducing new controls for delegate access to encrypted emails accessed via Outlook clients other than Outlook for Windows. The controls are implemented in three new PowerShell cmdlets which can block, validate, and allow delegate access to encrypted messages. It’s nice to see some coherence being introduced for almost all the Outlook clients, even if Outlook for Windows does its own thing.

Guest Accounts Can’t Update Their Photos with the Microsoft Graph PowerShell SDK

The Azure AD PowerShell module allows guest accounts to sign into target tenants and update their account photo there. The Microsoft Graph PowerShell SDK includes a cmdlet to do the job, but it doesn’t work when connected to a target tenant. Permissions are the reason why, which is what we explain in this article.

How Many Teams Compliance Records Are in Your Tenant?

The Microsoft 365 substrate captures Teams compliance records for chats and channel conversations and stores them in Exchange Online. How many do you have? Although you might not care, sometimes it’s good to know (like a tenant to tenant migration), so we explain how to count Teams compliance records for chats and channel conversations.

Graph X-Ray Tool Helps PowerShell Developers Master the Graph

The new Graph X-Ray extension available for the Chrome and Edge browsers gives developers an insight into how the Azure AD admin center uses Graph API commands to retrieve user and group objects. The insight is invaluable when teasing out some of the syntax needed to get work done with the Graph. It’s much appreciated.

Using the Graph API to Generate Mailbox Folder Statistics

A reader asked if it’s possible to use PowerShell to return the unread count for the Inbox folder in user mailboxes. The standard Exchange Online PowerShell cmdlets tell you a lot about mailbox folder statistics, but they can’t look inside a folder. But the Microsoft Graph APIs can, so a combination of PowerShell and the Graph deliver a solution to the problem.

Basic Authentication Deprecation Can Stop Exchange Online Scripts Working

The upcoming removal of support for basic authentication in seven Exchange Online connectivity protocols could mean trouble for some Office 365 tenants if they don’t take care to ensure that modern authentication is used for PowerShell connections. The old-style Remote PowerShell connection must be replaced with the Connect-ExchangeOnline cmdlet from the Exchange Online management module (aka the V2 module). Apart from anything else, this should improve the performance and robustness of scripts, especially after Microsoft finishes the work to remove the WinRM dependency for older cmdlets.

ImportExcel PowerShell Module Worthwhile Addition to Microsoft 365 Admin Toolkit

The ImportExcel PowerShell module is a useful addition to any Microsoft 365 tenant administrator’s toolbox. Although standard cmdlets exist to interact with spreadsheet data, they are limited to CSV files and can’t exploit the full power of Excel in the way that ImportExcel can do, all without needing to install the Excel application on a workstation.