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.
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=22.214.171.124, 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.
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!
- How to fix NU3028 and NU3037 errors in Azure DevOps builds? - September 20, 2022
- How to kill the process causing the “MSB3021 Unable to copy file — The process cannot access the file because it is being used by another process.” error? - September 13, 2022
- How to replace and reload application settings changes in .NET? - September 6, 2022