I secretly automated my whole job with PowerShell

How to use Microsoft.Online.SharePoint.PowerShell with PowerShell 7?

This post was most recently updated on August 26th, 2022.

2 min read.

This article explains an annoying extra step (or a really nifty trick – depending on how you choose to look at it!) that you can take to make sure your PowerShell 7 is able to import a module that was developed for .NET Framework, instead of .NET Core.

This is super helpful when you run into weirdness with some of the more, let’s call them CLASSICAL, PowerShell modules. Such as Microsoft.Online.SharePoint.PowerShell.

Problem

I use PowerShell 7 as the default shell in my Windows Terminal. It doesn’t exactly play nice with Microsoft.Online.SharePoint.PowerShell, though – as the module was built with .NET Framework and doesn’t work as-is in PowerShell that’s built on .NET Core (or later just .NET).

Weirdly, you can import it, and it might partially work – or you might get an error like this:

Connect-SPOService: Could not load type 'Microsoft.SharePoint.Client.SharePointOnlineCredentials' from assembly 'Microsoft.SharePoint.Client.Runtime, Version=16.1.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'.

Or maybe you’ll just fail miserably when running something like Connect-SPOService:

Connect-SPOService: The remote server returned an error: (400) Bad Request.

How nice.

Solution

To my surprise, importing modules to PowerShell 7 actually supports importing them in Compatibility Mode – which in this case means that an older module will actually work just like it should!

And for once, it is actually straightforward to use! Whoever implemented this, did a pretty good job hiding the complexity, since you just add the “-UseWindowsPowerShell” switch to your Import-Module command, and that’s it.

Microsoft actually has decent documentation for the feature:

Using the Compatibility feature

When the first module is imported using Windows PowerShell Compatibility feature, PowerShell creates a remote session named WinPSCompatSession that is running in a background Windows PowerShell 5.1 process. This process is created when the Compatibility feature imports the first module. The process is closed when the last such module is removed (using Remove-Module) or when PowerShell process exits.

The modules loaded in the WinPSCompatSession session are used via implicit remoting and reflected into current PowerShell session. This is the same transport method used for PowerShell jobs.

When a module is imported into the WinPSCompatSession session, implicit remoting generates a proxy module in the user’s $env:Temp directory and imports this proxy module into current PowerShell session. This allows PowerShell to detect that the module was loaded using Windows PowerShell Compatibility functionality.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_windows_powershell_compatibility?view=powershell-7.2

So, in essence, to use Microsoft.Online.SharePoint.PowerShell in PowerShell 7, simply import the module in “Windows PowerShell compatibility mode”, like so:

Import-Module Microsoft.Online.SharePoint.PowerShell -UseWindowsPowerShell

And there you go!

mm
5 3 votes
Article Rating
Subscribe
Notify of
guest

2 Comments
most voted
newest oldest
Inline Feedbacks
View all comments