Graph and PowerShell Hiccups for the Groups and Teams Report Script

The Microsoft 365 Groups and Teams Activity Report is a PowerShell script that I’ve worked on since 2016 (not all the time). Some recent Graph hiccups meant that I had to apply some fixes and workarounds. At the same time, some users hit the infamous ‘not recognized as a valid datetime’ problem, so another update was needed. All good, clean fun.

Does Microsoft Care about SharePoint Online PowerShell?

Microsoft’s support for SharePoint Online PowerShell has degraded over the last few years. Pnp.PowerShell is now the best option as not much is happening in the official SharePoint Online management module or the tenant settings Graph API. the lack of progress is a pity, but perhaps it’s also true that community-driven projects sometimes deliver better results.

Despite the Doubters, Microsoft 365 Administrators Should Continue Using PowerShell

A recent article by a Microsoft MVP attempted to lay out a case that tenants should not use Microsoft 365 PowerShell and use ISV products instead. It’s a silly position to argue. PowerShell is an important automation tool for administrators that can’t be replaced by any ISV product. ISV products have their place and fill many gaps, but arguing to dump PowerShell and use ISV products instead just can’t be justified.

Report OneDrive for Business Storage Based on Usage Data

If you wanted to write a PowerShell script to create a OneDrive storage report, you’d probably use the cmdlets from the SharePoint Online management module. But accessing OneDrive usage data via the Graph is much faster. And you can include information from other sources, such as user properties, to build out the report. All explained here.

Why You Should Not Upgrade to Microsoft Graph PowerShell SDK V2.14

Usually, we recommend that Microsoft 365 tenants use the latest version of the Microsoft Graph PowerShell SDK. However, a serious bug in V2.14 means that this (and perhaps V2.13.1) should be avoided until Microsoft fixes a problem that causes spurious output to be included when cmdlets like Get-MgUser and Get-MgGroup are run.

Tracking Licensing Costs for Microsoft 365 Tenants

The latest version of the Microsoft 365 Licensing Report script includes code to generate cost analyses for the departments and countries assigned to user accounts. Everything works well if the properties of Entra ID user accounts are complete and accurate. Sometimes this isn’t so, and that leads to problems when attributing costs at a department or country level.

How Many Message Center Announcements End Up Being Delayed?

This article describes how to use the Microsoft Graph PowerShell SDK to retrieve and interpret Microsoft 365 message center posts with the intention of discovering what percentage of announcemengts end up being delayed (not being available at the predicted date). Teams makes lots of feature announcements and over 57% of those announcements are delayed.

Use the Graph SDK to Access Microsoft 365 Service Health Information

The Microsoft Graph includes the Service Communications API. SDK cmdlets can use the API to retrieve and work with service health data. In this article, we show how to use Graph SDK cmdlets (based on the API) to fetch and work with service health data, including creating an email report to update people about the current state of tenant health.

New MSIdentityTools Cmdlet to Report OAuth Permissions

The latest version of the MSIndentityTools PowerShell module includes the Export-MsIdAppConsentGrantReport cmdlet to generate a report of OAuth app permissions. Allied with the ImportExcel module, the cmdlet can produce a very nice workbook containing lots of information about permissions held by the apps in a tenant. But even better, you can export the data to PowerShell and use it in your scripts.

Microsoft Deprecates Old Exchange Audit Search Cmdlets

A January 26 post announces the deprecation of four old Exchange audit cmdlets in favor of the Search-UnifiedAuditLog cmdlet. Removing old cmdlets is fine, but it would be nice if Microsoft took the opportunity to make Search-UnifiedAuditLog work better. Too many inconsistencies exist in how workloads provide information in audit events and Microsoft has made some recent unannounced changes.

Mastering Microsoft Graph PowerShell SDK Foibles

Entra ID supports user extension attributes but the same facility is unavailable for group objects. That seems strange, but it might be due to the way that Entra ID thinks about group object. In any case, it’s an inconsistency that Microsoft should address. Also covered is how to report problems with Graph SDK cmdlets and a new function to help you understand the permissions needed to run a script.

Reporting Entra ID Admin Consent Requests

A question came in about how to report admin consent requests as viewed through the Entra ID admin center. PowerShell does the trick, once you know how. The key thing is to find the right cmdlet to use. Once you know that, the rest is pretty easy as we explain in this article.

Entra ID Improves Registered App Security

The preview app instance property lock feature designed to improve the security of Entra ID registered apps is becoming the default for new apps. In this article, we describe how to update the app instance property lock to reflect the new default setting using cmdlets from the Microsoft Graph PowerShell SDK, including a script you can download and run.

Reporting User and Group Assignments for Enterprise Applications

A reader asked how to report user and group assignments for enterprise apps. As it turns out, this isn’t particularly difficult, if you know where to look. Our script uses the Graph SDK to check service principals, filters out the apps to check, and extracts the user and group assignments before reporting what it finds.

A New Approach to Reporting Exchange Mailbox Statistics

Exchange mailbox statistics reports are usually produced using PowerShell cmdlets. However, using Graph usage data is a faster way to process mailboxes because it avoids the need to fetch mailbox statistics by running a cmdlet for each mailbox. This article describes how to speed things up in a way that will probably benefit larger organizations most, but every Exchange Online tenant can probably benefit.

Report Email Proxy Addresses for Exchange Online Mail-Enabled Objects

This article explains how to use PowerShell to report the email proxy addresses assigned to Exchange Online mail-enabled objects. Creating the list is straightforward, but figuring out how to use the list afterwards might need more creativity. To get things going, we show how to load the list into a hash table to resolve email addresses into display names.

Reporting the Storage Used by Loop Workspaces

When Microsoft put the Loop app into preview, they didn’t impose any restrictions in terms of licensing or workspace storage. MC678308 announces that Loop workspace storage will count against the tenant SharePoint Online storage quota. This article explains how to use the Get-SPOContainer cmdlet to fetch information about Loop workspaces and the storage they consume.

Reducing the Memory Footprint of Exchange Online PowerShell

The Exchange Online developers issued three recommendations to improve performance and reduce memory consumption for Exchange Online PowerShell sessions, specifically those used by automated scripts that don’t involve human interaction. I think two of the recommendations are very practical and worth implementing by everyone, even if you think everything is good with PowerShell.

Using Microsoft Graph SDK Cmdlets to Create a SharePoint Online List

An article last week discussed how to create SharePoint lists with the PnP.PowerShell module. In this article, we do the same with cmdlets from the Microsoft Graph PowerShell SDK. The results achieved with the Graph SDK aren’t as good as those gained with PnP.PowerShell. Some of the SDK cmdlets don’t function as expected and the resulting list is not as functional as the one generated by PnP. Oh well…

Creating a Teams Directory in a SharePoint Online List

This article explains how to create SharePoint lists using cmdlets from the PnP.PowerShell module. The original data comes from a script to create a Teams Directory in HTML and CSV format files. The CSV data is imported into SharePoint to populate a list in a communications site. Everything works very smoothly, which begs the question why this kind of import isn’t done more often. Perhaps it’s because people don’t know that it’s possible. They do now.

Teams and Microsoft Exchange PowerShell Modules Clash Over Required DLL

After updating a bunch of PowerShell modules, I was dismayed to find a PowerShell module clash caused by a dependency on the Microsoft.Identity.Client DLL. The Exchange Online management module wanted a higher version of the DLL than the one loaded by the Teams module, so the Connect-ExchangeOnline cmdlet barfed. It’s easy to understand the logic behind the problem, but it’s hard to understand why Microsoft let it happen.

How to Control the Creation of Microsoft 365 Groups with the Microsoft Graph PowerShell SDK

Microsoft suggests that allowing every user to create new Microsoft 365 groups. That’s mad. Controlling group creation through policy settings is the only way to go. It will avoid group sprawl (or team sprawl) and avoid a lot of administrative effort that will otherwise be devoted to cleaning up the mess of unused and unwanted groups. This article explains how to update policy settings to control group creation using cmdlets from the Microsoft Graph PowerShell SDK.

How to Execute Bulk Updates of Primary SMTP Address for Distribution Lists

Exchange Online

Like any mail-enabled object managed by Exchange Online, distribution list proxy addresses determine if Exchange can deliver messages to an object. Sometimes the proxy addresses aren’t correct or need adjustment, such as in the case when an organization wants to make sure that all distribution lists have primary SMTP addresses from a specific domain. This article explains how to use PowerShell to adjust the primary SMTP address when necessary.

Microsoft 365 Groups with Long Names Cause Graph Errors

Microsoft 365 group display names longer than 120 characters will cause problems for Graph API requests attempting to fetch the groups. A workaround exists, which is to make the request an advanced query rather than a regular one. But the question really should be “who needs group display names that are longer than 120 characters?”

How to Block User Access to Microsoft 365 PowerShell Modules

The question of how best to block PowerShell access for Microsoft 365 user accounts deserved some consideration. The answer lies in service principals for the enterprise accounts created by Microsoft to allow PowerShell modules to authenticate with Entra ID. By restricting access to an assigned security group, you effectively block access to anyone outside that group.

How to Remove Licenses From Disabled Accounts with PowerShell

This article explains how to use PowerShell to remove licenses from disabled accounts, including some caveats such as not removing Exchange Online licenses. Organizations might want to do this to save money on Microsoft 365 license fees while an account is temporarily unused. Removal of Exchange Online licenses can result in the loss of a mailbox, and you don’t want that to happen if you’re disabling accounts just because someone is on a long-term sabbatical or other leave of absence.

How to Create Dynamic Microsoft 365 Groups (and Teams) for Departments

This article explains how to use PowerShell to create dynamic Microsoft 365 groups (and teams) based on the departments assigned to Entra ID user accounts. Creating a new group is easy. The trick in team-enablement is to wait for the synchronization between Entra ID and Teams to finish before you go ahead. After that, it’s plain sailing.

Microsoft Removes Exchange Online User Photo Cmdlets

Microsoft announced that they will deprecate the user photo cmdlets from Exchange Online from November 30, 2023. Microsoft Graph PowerShell SDK cmdlets replace the EXO cmdlets because user photo data is stored in Entra ID. Although inconvenient for those who need to update scripts, this is part of an effort to rationalize how Microsoft 365 handles user profile information.

How to Convert Custom Background Images for Teams 2.1

The Teams 2.1 client uses a different folder and naming convention for custom background images. People who switch must move their images, so here’s a script to do the job by resizing images to meet Teams requirements, renaming the files to comply with the new naming scheme, and copying the files from the old to the new folder, It’s PowerShell, so you can change the code as you like.

How to Update Shared Mailbox Owners About Quota Usage

An old script created to report quotas for user mailboxes provided the basis for email-based reporting of shared mailbox quotas. The old script used just Exchange Online PowerShell. This versions mixes Exchange Online and the Graph SDK and throws in some certificate-based authentication to boot to allow the script to send email from something other than the signed-in account.. It all comes together, using chunks of code from other scripts to speed up writing. It’s the PowerShell way…

How to Monitor New Members Added to Teams

I was asked how easy it would be to write a PowerShell script to monitor new teams members and reject any additions that met specific criteria. Easy, we said, so we set to creating a script to interrogate the unified audit log to find new member events. Once that was done, it’s a matter of analyzing the events to find if we should reject the addition of any of the added members.

How to Analyze User Email Traffic by Internal or External Destination

After writing a previous article about using PowerShell to analyze message trace data, I was asked about analyzing user (or mailbox) sending patterns to discover who’s sending email and where they’re sending messages to. As in many similar situations, PowerShell is a great tool to use because of its flexibility. This article explains how to generate a per-mailbox report of how many messages are sent and the percentage of internal versus external, plus the external domains the email goes to.

How to Create Dynamic Administrative Units with PowerShell

A reader asked how they could create dynamic administrative units for every department in their directory. A PowerShell script does the job, even if some constraints in how Entra ID processes membership rules means that the rules can’t be quite as precise as I would like them to be.

Chasing Performance When Reporting Teams SharePoint Site URLs

It’s possible to use PowerShell to create a report detailing the SharePoint Online site URLs used with Teams. My first attempt used the Exchange Online module, but is the Graph any faster? As it turns out, not really. At least, not for interactive sessions using the Microsoft Graph PowerShell SDK (things are different when running SDK code using a registered app). I tried several approaches, but Graph permissions got in the way every time.

Use Message Trace Data to Analyze Email Traffic

This article describes how to use PowerShell to extract and analyze Exchange Online message trace data to figure out the volume of traffic to outbound domains and from inbound domains. You might think that this is the same information as available in the Exchange admin center mail flow report, but it’s not. Once again, the value of PowerShell in retrieving and using data is evident.