Microsoft 365 for IT Pros (2027 Edition)

It is that time of year again. The new edition of Microsoft 365 for IT Pros is out, and this one brings the biggest structural change we have made in years. What used to be one large book with a single companion volume has now grown into a bundle of four focused books. Splitting the content allows us to go deeper while keeping the main book maintainable. Together, they deliver more than 1,700 pages of practical guidance for people who run Microsoft 365 every day.

A bit of history

The series goes back to May 2015, when it started life as Office 365 for Exchange Professionals. Over time, the platform expanded, the audience broadened, and the book evolved with it. This year also marks the move from Office 365 for IT Pros to Microsoft 365 for IT Pros. The name changed, but the focus did not. We still cover the services and workloads administrators, architects, and technologists rely on.

I joined the writing team in 2024. What stood out to me from day one is that this is not a traditional technical book. Most books age the moment they are published. This one does not. We update it every month and keep tracking the constant stream of changes across Microsoft 365. That evergreen model, combined with real-world experience, is what makes this book stand out. It is written for people who manage Microsoft 365 daily and need the most up-to-date content.

What you get

The bundle now consists of four books, each focusing on a specific area:

  • Microsoft 365 for IT Pros is the core book. It covers the Microsoft 365 ecosystem from an administrative perspective, including identity, Exchange Online, SharePoint Online, Teams, OneDrive, and overall tenant management. This edition adds a dedicated AI and Agents chapter covering architecture, licensing, deployment, governance, monitoring, and cost control for Copilot and related technologies.
  • Automating Microsoft 365 with PowerShell is the PowerShell / automation book. It focuses on automating Microsoft 365 with PowerShell and Microsoft Graph, providing practical examples you can apply in real-world environments.
  • Microsoft Purview for IT Pros is a new standalone book. It covers compliance and data governance, including data lifecycle management, eDiscovery, data loss prevention, information protection, and communication compliance.
  • Power Platform for IT Pros is the 2nd new standalone book. It focuses on the administration and governance of the Power Platform, including environments, Dataverse, solutions, application lifecycle management, and platform security through policies and controls. It also covers scenarios for Power Apps, Power Automate, AI Builder, and Copilot Studio.

Splitting the content into separate books allows for more depth and focus, while making the core book easier to consume and maintain. And for those who need it, each companion book is available separately, offering the same monthly updates for that book throughout the subscription.

Who this is for

Tenant administrators, consultants, architects, engineers, and technical leads will get the most value from this edition. If your job involves Exchange Online, Entra ID, SharePoint Online, Teams, OneDrive, Purview, Power Platform, Copilot, PowerShell, or Microsoft Graph, this set has been designed for you.

Availability

We use Gumroad.com to publish and distribute the books. All books are available in EPUB and PDF formats and can be converted for use on Kindle devices.

You can get the books here:

Challenges of PowerShell Scripting with Microsoft 365

If you are looking for a way to automate and simplify your Microsoft 365 administration tasks, PowerShell is a great option. However, PowerShell scripting is not without its challenges. Not proactively maintaining code can quickly become an issue because of the changes made to dependencies such as modules, as well as the cmdlets you use.

In an article I wrote for Practical 365, related to the presentation of the same name held at the The Experts Conference 2023 in Atlanta this year, I discuss some of the challenges administrators might encounter with PowerShell scripts. Also, I provide some guidance and point out a few tools that can assist with rewriting or refactoring code, i.e., updating code while keeping its external functionality.

Click here to read the full article on Practical 365.

Hosting MTA-STS policy using GitHub Pages

The MTA-STS policy (MTA Strict Transport Security) is to prevent Man-In-The-Middle attacks by publishing authorized mail servers and prevent TLS downgrade attacks (Opportunistic TLS), when both parties support MTA-STS. MTA-STS is easier to implement over DANE with DNSSEC, which is expected to get inbound support in Exchange Online next year. Since I am using WordPress to host this blog, I was looking for ways to host the policy file for MTA-STS at the required location, as hosted WordPress does not offer this possibility.

There is documentation describing how to accomplish this using, for example, Azure Static Web Sites, but this requires an Azure subscription. There are also 3rd parties offering hosted MTA-STS, which are usually not free.

Then I stumbled upon the possibility of using a custom domain with GitHub pages, which can be used for this. So, here is a quick write-up on how to host your MTA-STS policy file on GitHub using GitHub Pages. This process could also be used when needed for hosting other files on GitHub.

Hosting MTA-STS Policy using GitHub Pages

Start by creating a new repository in GitHub. You can name it anything you want, but for the sake of the example, I called it mta-sts. Make sure it is public.

Next, we must create an empty file called .nojekyll in the repository. This file will instruct GitHub not to build pages, and just serve your files. So, Add file > Create new file, enter .nojekyll as Name your file and Commit changes.

Now, create the policy file that needs to be named mta-sts.txt in the .well-known folder file, select Add file > Create new file and enter .well-known/mta-sts.txt as the name of your file. This will also create the required folder. In the contents field, paste your policy. For example, the MTA-STS policy file when using only Exchange Online for receiving e-mail could look something like this:

version: STSv1
mode: testing
mx: *.mail.protection.outlook.com
max_age: 604800

When done, commit your changes to store the policy file on GitHub. For more information on the MTA-STS policy file definition, click here.

Next, we need to enable GitHub Pages for this repository. Go to Settings, and select the Pages tab. Under Branch, select the branch you want to publish, eg. main, and press Save. Note that GitHub Pages are served using a valid 3rd party certificate, which satisfies one of the requirements for MTA-STS.

New options should now appear on the GitHub Pages settings, one of which is Custom domain. If you decided to use a custom domain in the previous step, enter it here, eg. mta-sts.contoso.com, and click Save.

GitHub will start to check DNS for the presence of this domain. Time to head over to your ISP portal, and create the required records in DNS.

First, if you used a custom domain for hosting the MTA-STS policy, create a CNAME mta-sts record for your domain pointing to <user>.github.io or <org>.github.io, e.g.

mta-sts.contoso.com CNAME 3600 user.github.io

Next, create the DNS TXT _mta-sts record to indicate MTA-STS support, e.g.

_mta-sts.eightwone.com TXT 3600 v=STSv1; id=202310041637

Note that you need to update ‘id,’ usually with timestamp yyyymmddhhmm, whenever you make changes to the policy. This indicates to MTA-STS supporting hosts there has been a change on your end.

You are now set. After DNS some time for DNS to propagate changes, you can start verifying your configuration by browsing https://mta-sts.contoso.com/.well-known/mta-sts.txt, which should return your policy file without any certificate prompts. You can verify DNS and policy access using websites like MxToolbox or PowerDMARC. The example below was generated using EasyDMARC:

TLS Reporting

In addition to setting up MTA-STS, you can configure TLS Reporting (TLS-RPT). This will instruct supporting servers to report on TLS usage and mention certificate issues, for example. Note that these are reports on inbound messages, whereas Exchange Online offers information on outbound TLS usage. To set up TLS-RPT, configure a DNS TXT record _smtp._tls and specify a recipient for these reports, e.g.

_smtp._tls.contoso.com TXT 3600 v=TLSRPTv1; rua=mailto:tlsreports@contoso.com

The rua field contains the e-mail address where reports should be sent. You can process these reports in JSON format yourself or have one of the 3rd parties offering this service do this for you. The example below is generated by Dmarcian.

Analyzing Exchange Online scripts

Updated: 1.2 adds default ExchangeOnlineManagement cmdlets scanning and authentication options.

Since the original announcement on deprecation of Basic Authentication, organizations had time to analyze their environment which may include Exchange-related procedures and tools. These usually also contain scripts or commands, which depend on the Exchange Online Management module. A previous blog on its history and how version 2 of this module lends itself for unattended operation with certificate-based modern authentication support can be found here.

The initial release of the Exchange Online Management v2 – or EXOv2 – module offered a an additional small set of cmdlets which utilized REST-based services. Apart from the functional discrepancies, such as having to specify a property set to indicate which properties to return, the big advantage of these added commands was that they did not depend on the Windows Remote Management (WinRM) client using Basic Authentication for token exchange. Disabling Basic Authentication on WinRM client lead to messages such as:

Connecting to remote server outlook.office365.com failed with the following error message : The WinRM client cannot process the request. Basic authentication is currently disabled in the client configuration.

This dependency makes it challenging for organizations to turn off Basic Authentication altogether, or lead to problems when they did. Fast forward to the present, where the Exchange Online Management module in its current release is offering nearly all Exchange cmdlets in REST-based form, with full functional parity.

While I expect Microsoft to reach full command parity before they flick the Basic Authentication switch to off, there are also other use cases for which analyzing scripts might be helpful:

  • Ths initial purpose was identifying commands which require RPS (Remote PowerShell), and thus thus require WinRM Basic Authentication enabled. Because the Exchange Team did an amazing job in catching up in the recent months, only few Exchange Online cmdlets are still lacking REST support in my tenant at this moment, e.g. New-ApplicationAccessPolicy. But then again, your mileage may vary, as the recent Preview 7 module removed few UnifiedGroup related cmdlets which had issues.
  • New Exchange Online commands may not receive immediate REST support.
  • Organizations might want to cross-reference commands with scripts.
  • Identifying Exchange Online commands and parameters in scripts helps in determining the minimum set of permissions required to run the script.

To analyze and report on Exchange Online scripts, I created a simple script Analyze-ExoScript.ps1. This script, which is available on GitHub here, does the following:

  • Connect to Exchange Online using RPS and inventory the commands available. Note that this requires the UseRPSSession switch when connecting, which is only available per 2.0.6-Preview3 of the module. If your organization only runs GA versions of the module, this script cannot be used.
  • Connect to Exchange Online using REST and inventory the commands available. It will re-use the account used for authenticating the RPS session, which should prevent receiving another authentication dialog or MFA challenge.
  • Cache cmdlet information in an external file to prevent having to connect to Exchange Online for every run. The file is named EXO-CmdletInfo.xml and will be stored in the same folder as the script.
  • Process the script and report on the Exchange-related commands used.

Usage
Calling Analyze-ExoScript is straightforward:

.\Analyze-ExoScript.ps1 [-File <FileName[]>] [-ShowAll] [-Refresh] [-Organization <String> -AppId <String> -CertificateFile <String> [-CertificatePassword <SecureString>] -CertificateThumbprint <String>] [-Credential <SecureString>]

Where:

  • File is the name of one or more files which you want to analyze. Note that the script accepted pipeline output, so you can also feed it filenames using Get-ChildItem for example.
  • The ShowAll switch tells the script to output all found commands, not only the Exchange ones.
  • The switch Refresh tells the script to ignore saved command information, trigger reconnecting to Exchange Online in order to refresh the command sets.
  • Credential specifies the (Basic Authentication) credential to pass to Connect-ExchangeOnline.
  • Organization and AppId can be used to specify the tenant ID (x.onmicrosoft.com) and registered application ID to use with Connect-ExchangeOnline using Modern Authentication. This also requires one of the following:
    • CertificateThumbprint of the certificate to use for authentication.
    • CertificateFile of the file containing the certificate to use, together with CertificatePassword to specify its password.

When asked to authenticate, make sure your role has the necessary Exchange-related permissions as that will determine the Exchange Online cmdlets available to you, and consequently also the commands which Analyze-ExoScript will recognize in scripts to process.

For example, to process a script Fix-MailboxFolders.ps1, use:

.\Analyze-ExoScript.ps1 -File .\Fix-MailboxFolders.ps1

The script can accept files via the pipeline. For example, to process multiple scripts use something like:

Get-ChildItem -Path C:\temp*.ps1 | Analyze-ExoScript.ps1

The output consists of objects, which allow for further filtering:

The returned properties are:

  • Command is the Exchange Online command identified
  • Type will tell you if the command supports REST or requires RPS.
  • Parameters are the parameters used together with the command. This includes common parameters, which might be less usable for role assignment purposes.
  • Alt contains alternative REST-based cmdlet you could consider using for performance reasons, e.g. Get-EXOMailbox instead of Get-Mailbox.
  • File and Line are the file containing the command and on which line it is located.

AST
To analyze code, I leveraged PowerShell feature called Abstract Syntax Tree, which was an interesting exploration in itself. PowerShell AST can be used to decompose PowerShell code into tokens. This is way better than simply looking for strings, and does away with having to interpret code yourself to see if something is a command, comment or just some string. AST allows for analysis of these tokens, in this case filtering on commands which are related to Exchange Online. If you want to get started on AST, check out this article, or plunge in the PowerShell SDK straightaway.

Final Words
When every Exchange Online command discovered is found to be offering REST support, you can turn off Basic Authentication on the client, for example through GPO or by reconfiguring WinRM:

winrm set winrm/config/client/auth @{Basic="false"}

Only thing you might need to refactor is if and how the script connects to Exchange Online, as Basic Authentication allowed for connecting to Exchange Online using (stored) credentials for example. Examples on how to use more secure Modern Authentication-based methods to connect can be found in an earlier article here.

The Last Exchange Server

In the announcement of the most recent set of Cumulative Updates for Exchange Server 2019 and 2016, Microsoft introduced some changes – features if you will – as well, which were received with enthusiasm. An overview of these Cumulative Updates and the features introduced was given in an earlier article. In this article however, I would like to zoom in on one of those features, which also happens to be a popular topic among customers running Exchange Hybrid deployments, “The Last Exchange Server”.

Up to Exchange 2019 CU12 (2022 H1), customers that migrated to Exchange Online were still required to leave Exchange-related components running on-premises. Even today, with all the information published around this topic, I am surprised this still surprised customers. This Exchange server running on-premises is to be used for managing recipients which have their source of authority in Active Directory, leveraging Active Directory Connect to propagate objects to Azure Active Directory and thus Exchange Online. Also, when there is a need to relay messages from applications or multi-functional devices, customers often need to have an Exchange server on-premises to accept these messages, as Exchange is the only supported mail relay product for hybrid deployments.

Click here to read the full article on ENow Solutions blog.