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.

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.

Basic Authentication: End of an Era


1sep2022: Added announcement regarding Jan2023 extension

Back in September 2019, Microsoft announced it would start to turn off Basic Authentication for non-SMTP protocols in Exchange Online on tenants where the authentication protocol was detected as inactive. This is part of an overall movement to deprecate the less secure Basic Authentication, which is unfit to face the security challenges of the modern world, being subject to things like password spray attacks. It’s modern successor, modern authentication or OAuth2, uses a token and claim based mechanism contrary to sending accounts and passwords, and is the preferred authentication method. When combined with Azure AD for authentication, Modern Authentication also supports features such as Multi-Factor Authentication or Conditional Access.

The original date for disabling of Basic Authentication was October 13th, 2020. Then the world had other matters to deal with, and Microsoft extended the timelines. After initially postponing turning Basic Authentication off to second half of 2021, the ‘start date’ for permanently turning the lights off for Basic Authentication was set to October 1st, 2022, as per this article on Docs and MC286990 in the Message Center. Mind the ‘start’ in start date, as flicking the switch for millions of tenants takes time before it becomes effective on your tenant. Organizations do need to anticipate on this change for the first of October.

On September 1st, Microsoft published an update to these timelines as there were still some cases were organizations could not make the deadline of October 1st. To meet these customers “one last time”, organizations can now use the self-service diagnostics to extend disabling of Basic Authentication to January 2023. This needs to be done per protocol, also if organizations requested opt-out or re-enabled Basic Authentication earlier. Details as well as instructions and revised timelines on Basic Authentication switching off are laid out in a new article.

Until then, organizations can (re-)enable Basic Authentication for the protocols they need, using the self-help system in the Microsoft 365 admin center. After entering “Diag: Enable Basic Auth in EXO” in the problem search query, the request will be checked, and Basic Authentication will get enabled. But with the end of support for Basic Authentication, so will this temporary workaround. On a side note, per end of 2020, newly created tenants already have basic authentication disabled by means of security defaults – if those organizations require Basic Authentication for some reason, they will also need to reconfigure security defaults which by default is an all or nothing option for all protocols.

So, with the doomsday counter ticking away for Basic Authentication, what are the consequences for Exchange related workloads organizations might wonder. In this article, I will address some of these concerns.

Update: Microsoft meanwhile has disclosed much awaited details on changes in the native Mail app on iOS. This update is effective per iOS 15.6, and adds support for migrating configured accounts from using Basic Authentication to using Modern Authentication (OAuth). For this work work seamlessly and without user interruption, some configuration is needed on the back-end. Details can be found in a separate article here on this specific topic.

Click here to read the full article on ENow Solutions blog. Note that the ENow article does not include later updates, such as the latest timeline revisions and iOS account conversion, both mentioned above.

Change Teams Guest Profile Picture


In tenants with lots of Guests, the massive display of user initials – the default profile picture – isn’t very pleasing to the eye. Now while regular user can change their profile picture, Guest users cannot. Therefor, a long standing and popular request on UserVoice has been the ability to change profile pictures for Guest users. End of 2020, this request was updated, indicating a change was planned to incorporate the ability to change this profile picture. No signs on the roadmap yet, so what options – if any – does one currently have?

Last week, Teams MVP Yannick Reekmans posted a blog containing instructions on how to change your profile picture for tenants in which you are a Guest. It requires quite some steps and fiddling to accomplish this. One might also wonder, isn’t this possible “the programmatic way”? Well, yes, and here are the steps:

First, open up PowerShell, install the AzureAD PowerShell module it is not yet installed using Install-Module AzureAD, and connect to Azure Active Directory, specifying the tenant where you are a guest:

Connect-AzureAD -TenantDomain contoso.onmicrosoft.com

When the authentication challenge pops up, specify the credentials of the Guest account and approve the Multi-Factor Authentication challenge when required.

Next, use Set-AzureADUserThumbnailPhoto to set the profile picture for your Guest account, specifying your User Principal Name as ObjectId, as well as the picture you want to use, e.g.

Set-AzureADUserThumbnailPhoto -ObjectId 'michel_fabrikam.com#EXT#contoso.onmicrosoft.com' -FilePath 'c:\pic.jpg'

Regarding the User Principal Name, you can use Yannick’s method of determining your Guest’s ID. You can also try to guesstimate it by taking the e-mail address of your original account, replacing ‘@’ with ‘_’, adding a trailing #EXT# followed by ‘@’ and the default domain of the hosting tenant. The picture can be JPEG or PNG format, size 100kb at most, and square dimensions work best.

To verify the image has been set successfully, use Get-AzureADUserThumbnailPhoto -ObjectId <ID>. Then, have some patience for the change to propagate throughout the directories and caching mechanisms. To verify your update was successful and your picture looks properly, you can close the Teams client, clear the locally cached Teams data by removing everything under %AppData%\Microsoft\Teams (Windows), and start Teams again.

To easily spot tenants where you are a guest user and not a regular user, you might want to alter your standard issue profile picture a bit. For example, I have added a text label ‘Guest’ to mine. It doesn’t look as good as the high resolution photos that you can store in Exchange Online, but it certainly looks less boring than a set of intilials.

Note that all of the above is not an officially supported way to manage this picture. So, until there is one, these steps might help you out.

Outlook Connectivity changes per Nov2021


In the past, using outdated clients with Microsoft 365 services was a matter of being in an unsupported state with all the risks that go with it. This meant, that things might not work or you could experience reduced functionality. Overall, things usually kept working with a few consequences or glitches here and there.

A change in this stance was announced today per Message Center bulletin MC229143:

To ensure that we meet performance expectations, we are updating the supported versions of Outlook for Windows that can connect to Microsoft 365 services. Effective November 1, 2021, the following versions of Outlook for Windows, as part of Office and Microsoft 365 Apps, will not be able to connect with Office 365 and Microsoft 365 services.

This means, running old unsupported Outlook versions will go from “possible performance and reliability issues” to becoming actively blocked. This block will apply to these versions in the table below; as indicated, these builds were surpassed somewhere in 2017:

ApplicationAffected BuildsBuild Superseded
Office 201315.0.4970.9999
and older
October 2017
Office 201616.0.4599.9999
and older
October 2015
Microsoft 365 Apps for Enterprise
(formerly Office 365 ProPlus)

Microsoft 365 Apps for Business
(formerly Office 365 Business

1705 and olderJune 2017

While it is true that many customers are stretching the lifetime of their on-premises products beyond their support dates, I’m sure – apart from functionality and management options – performance and reliability is becoming more and more of an issue.

Finally, when this notice concerns you, it means you have not been updating your clients for at least 3 years. So, get planning, as you have around 11 months to update your clients. It also may affect any existing plans of moving to Exchange Online in the future, as getting your client-base in a supported state will become a requirement, and will no longer be a serious recommendation.

Self-Service Purchasing II


November 3rd, 2023: Updated SKU table with Clipchamp. Be advised, the MSCommerce module does not work with PowerShell 7 and requires compatibility mode (use Import-Module with -UseWindowsPowerShell).

It was in October 2019, that by means of Message Center bulletin MC163609 Microsoft announced that end users would receive the self-service purchasing option for Power Platform licenses (PowerBI, PowerApps and Flow). The announcement received quite some negative feedback, mostly because of the absence of administrative controls, with the risk of bypassing corporate purchasing as well as potential legal implications. Microsoft delayed the introduction, to launch it few months later in January this year, including the much requested controls.

Now MC220282 has appeared in the Office 365 Message Center, which announces the same self-service purchasing options for Microsoft Visio Plan 1 & 2 and Microsoft Project Plan 1 & 3. These purchasing options becomes available per September 15th.

The Message Center bulletin reads, “This change will not impact any existing settings you may have in place to manage self-service purchasing”. While true, administrators still might be faced with unexpected self-service capabilities for these new licenses. In this blog, I’ll talk you quickly through how to start managing these self-service capabilities, and how to modify these new ones.

Connecting and Managing

To start managing self-service capibilities, you need to install the MSCommerce PowerShell module, which Microsoft published at the PowerShell Gallery:

Install-Module MSCommerce

If you previously installed MSCommerce, update your module using:

Update-Module MSCommerce -Force

The current version of the module at the time of writing is 1.6. Now, to starting using the cmdlets provided in the module, you need to first connect to your Office 365 tenant:

Connect-MSCommerce

After completing login and succesfully completing any multi-factor authentication challenge, you can inspect the current self-service capabilities policy. First, there is a global policy named AllowSelfServicePurchase, which can be inspected using:

Get-MSCommercePolicies | Select PolicyId
Get-MSCommercePolicy -PolicyId AllowSelfServicePurchase | fl

As you can see, the default option for purchasing options is set to Enabled. This value can’t be modified, which means every new product added to self-service purchasing will be enabled by default. This also means admins may need to monitor the message center for self-service purchasing changes, and when required proactively monitor and disable this capability for new products. To inspect the current setting for every current product, use:

Get-MSCommerceProductPolicies -PolicyId AllowSelfServicePurchase

As you can see, the self-service purchasing for the Power Platform products have been disabled. However, because the DefaultValue is Enabled, the purchase capabilities for these new products have been set to Enabled. If we want to disable this capability for these products, use the following cmdlet:

Get-MSCommerceProductPolicies -PolicyId AllowSelfServicePurchase | % { Update-MSCommerceProductPolicy -PolicyId $_.PolicyId -ProductId $_.ProductId -Enabled $false }

Note that self-service purchase capabilities are not available for Office 365 Government, Nonprofit, and Education tenants.

Approval Flow

In another bulletin (MC213897), Microsoft announced the roll-out of an feature for end users to request licenses trough a customizable message or workflow. This option should become available when self-service purchasing has been disabled. It allows admins assign requested licenses from the pool or make required purchases, and also report on these requests to track interest. The bulletin has been updated recently to mark completion of roll-out of the message part of this feature; the request part is scheduled for completion in September. Unfortunately, I haven’t been able to locate settings related to these features yet, but these might appear any time soon. The screenshot from the bulletin gives an indication of what to expect:

To read more information on Self-Service Purchasing capabilities in the Self-Service Purchase FAQ.

Windows 365
Per MC271483, Microsoft informed Office 365 customers in July 2021 end users are going to be able to buy Windows 365 (announcement) licenses through the self-purchase license mechanism as well. Windows 365 will come in 2 flavors: Windows 365 Enterprise and Windows 365 Business; the latter is aimed at smaller organizations, while the Enterprise edition will offer Cloud PCs with Endpoint Manager and Defender integration a.o. A third Hybrid Benefit license option is available if you already have Windows 11 Pro or Windows 10 Pro on a device.

The Windows 365 SKUs are mentioned in the table at the end of this article.

If you did not configure the self-service puchasing option as disabled by default, you can disable new Enabled options using the code example above, or if you need to block these individual Windows 365 options upfront, use the following processing the Windows 365 SKU’s:

$W365Options= 'CFQ7TTC0HHS9', 'CFQ7TTC0HX99', 'CFQ7TTC0J203'
$W365Options | % { Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId $_ -Enabled $False }

Trials
On December 17th, 2021, it was announced through the Message Center (MC306669) that per January 26th, 2022, self-service purchasing would also allow sign-up for Visio (Plan 1 or Plan 2) or Project (Plan 1 or Plan 3) trials. There are no separate SKUs for this, as it is managed by disabling the existing Visio or Project options.

SKU Overview
The available self-service purchasing options per July 2022 are contained in the table below. However, these entries are subject to change and may vary depending on your region or type of tenant, i.e. commercial or government.

SKUDescription
CFQ7TTC0KP0NPower Automate per user
CFQ7TTC0KP0PPower Apps per user
CFQ7TTC0L3PBPower BI Pro
CFQ7TTC0HDB1Project Plan 1
CFQ7TTC0HDB0Project Plan 3
CFQ7TTC0HD33Visio Plan 1
CFQ7TTC0HD32Visio Plan 2
CFQ7TTC0KXG6Power Automate RPA
CFQ7TTC0KXG7Power BI Premium (standalone)
CFQ7TTC0HHS9Windows 365 Enterprise
CFQ7TTC0J203Windows 365 Business
CFQ7TTC0HX99Windows 365 Business with Windows Hybrid Benefit
CFQ7TTC0HVZGViva Learning
CFQ7TTC0LH3NDynamics 365 Marketing
CFQ7TTC0LHWPDynamics 365 Marketing Attach
CFQ7TTC0LH05Microsoft 365 F3
CFQ7TTC0LHVKDynamics 365 Marketing Additional Application
CFQ7TTC0LHWMDynamics 365 Marketing Additional Non-Prod Application
CFQ7TTC0N8SSClipchamp
CFQ7TTC0PW0VViva Goals
CFQ7TTC0LSGZPower Automate Per User with Attended RPA Plan
CFQ7TTC0S3X1Python On Excel
CFQ7TTC0J1FVTeams Exploratory
CFQ7TTC0RM8KTeams Premium
CFQ7TTC0N8SLMicrosoft Purview Discovery

Blocking Self-Service Purchases


o365logo

On October 23rd, Microsoft announced – a little out of the blue – they were going to introduce self-service purchase options for users on November 19th. The details of this change were put forward in a post in the message center, article MC193609 to be exact. In short, this option would introduce the following changes for commercial tenants:

  • Allow end users to purchase Power Platform related subscriptions using their own payment method, e.g. Power Apps, Automate (formerly Flow) or PowerBI Pro.
  • These subscriptions could be made in their employee’s tenant, with the exception of government, non-profit and education.
  • It would not end with Power Platform subscriptions.
  • To make purchases, end users would be able to open a restricted view of the Microsoft 365 Admin Center.

While a handful individuals cheered ‘Power to the end user’, the vast majority of organizations were very unhappy with this development to say the least. This adoption booster would not only be opposing Microsoft’s own ‘Cloud on your terms’ and ‘Your tenant, your data’ principles they have been telling customers for years, it could also severely impact enterprise security and governance policies (or absence thereof), let alone lead to discussions when people expense their PowerBI Pro purchase. And I’m not even talking about the absence of admin controls.

So, swiftly after the massive backlash on social media, UserVoice as well as other channels, the announcement was altered, and a FAQ was published, which you can read here. The change itself was postponed until January 14th, 2020, and organizations would be handed controls to turn self-service purchases off before roll out.

Rather quietly, details on how to disable self-service purchase have been added to the FAQ. To read on how to accomplish this, continue reading my original blog post over at ENow by clicking here.

Multi-Tenant Administration


imageNote: When writing this blog, the Azure portal received an update which allows for switching directories. Unfortunately, this feature hasn’t been ported to the other Office 365 admin UI’s at this moment.

Being a consultant, you often find yourself having to switch tenants, or having to keep multiple admin portals open to different Office 365 tenants. This may become a nuisance, as you can use only a single set of credentials per browser instance. In other words, if you connect to the Office 365 admin portal using credentials A, opening up the Azure portal will be in the same context.

A typical workaround for this situation would be to open up a new private browser session. From that private browser session, you need to provide credentials B. Any new tabs in that private window will also be in the same context. The whole private session is hosted in a new window.

A more neat solution for this scenario is leveraging browser containers, such as:

Notes:

  • This blog is written based on Firefox Multi-Account Containers, so your mileage may vary if you’re using Chrome or a 3rd party add-on.
  • Firefox also supports a basic version of context switching natively via about:config, setting privacy.userContext.enabled.
  • I’m not aware of similar features or 3rd party add-ons for other browsers.

imageUnlike the Chrome extension, FireFox’ Multi-Account Containers allows you to have multiple sessions from within the same browser. For this purpose, tabs are used to arrange sessions in what’s called containers. Each container shares the same set of site preferences, sessions, cookies etc. To identify containers, they can be assigned a (new) name, color and symbol.

After installing the add-in, you will get a button that will open the container selection window. In this example, I have set up 4 containers besides the default ones: one for every customer and one for my lab. Selecting Contoso will open a new blank tab. The right side of the address bar contains a visual reference to the active container, showing label and symbol in the configured color.

Keep Me Signed InNow, when you go to portal.office365.com, the Office 365 account picker may show up when connected before using this container. Pick one, or enter a new set of credentials. This account will be stored in this container. The question of wanting to stay signed in makes more sense now, as the token will be stored within the container, happily coexisting with other Keep-Me-Signed-In settings and sessions from other containers.

Now, when you open a different admin app in that tab, it will be in the same container and thus user context. You can also select to open a blank tab in that container, and navigate to portal.azure.com. You will notice it picks up the Contoso credentials provided earlier. This is because the session information is stored within the Contoso container.

image

Now click the container icon again, and select a different container, e.g. Fabrikam. Navigate to portal.office365.com, and you will notice you can provide new (or re-use) credentials which have a different context than Contoso. Also, opening the Azure portal after that in this container will be in the Fabrikam context.

Having set this up properly, you can easily switch between all admin portals from different tenants by selecting the different container tabs: no need to switch accounts or firing up separate private browser windows. This is a more elegant solution compared to private browsing sessions.

A final note that the above not only can be used to access the Office 365 admin portals of multiple tenants, but web-based applications such as Teams, Outlook Web Access or SharePoint as well.

 

Hybrid Configuration Wizard & F12


A small tip for those running the Exchange Hybrid Configuration Wizard. As announced at Ignite yesterday, a convenient feature was added to the HCW and is available now. Pressing F12 in the HCW will now open up a panel with shortcuts to the following tools and locations:

  • Exchange Management Shell
  • Exchange Online PowerShell
  • (current) Hybrid Configuration Wizard Log File
  • Create Support Package (to zip HCW logs for support)
  • Open Logging folder (of HCW)
  • Open Process Folder (of the HCW app)

Here is how it looks:

image

This might save you an occasional click or two.