Exchange Online PowerShell v2 Module Preview – Now More Secure
Published Nov 03 2021 11:56 AM 62.7K Views

Update 5/24/2022: We have now enabled all of the cmdlets to be REST-backed if you are using the 2.0.6-Preview6 module.

We’re excited to let you know that we are working on a new version of the Exchange Online PowerShell v2 module, built to provide a more secure experience for Exchange Online management. This module (available now in preview as Module 2.0.6-Preview3) enables IT admins to use their Windows client machines for day-to-day management of Exchange Online in their organization without enabling WinRM basic auth!

What’s new in this Preview?

The new module allows admins to connect to Exchange Online using Connect-ExchangeOnline, which now invokes a REST API in the background, making the cmdlets more reliable. Because a Remote PowerShell connection is not established in new version, this version doesn’t require WinRM basic auth to be enabled. You can disable WinRM basic auth by running the command below:

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

Read more about WinRM basic auth here.

A few things to note:

  • This is important to understand: not all cmdlets have been converted to use REST at this time. This is a preview module that supports only a portion of all cmdlets.
  • This version allows you to use all cmdlets via a Remote PowerShell connection as well. For that, you need to pass the -UseRPSSession parameter while running Connect-ExchangeOnline.
  • If you disable WinRM basic auth, the only cmdlets that will work with this module are the ones in the attached list; other RPS cmdlets will not work without WinRM basic auth at this time.
  • Please note that the work to enable cmdlets to run without WinRM basic auth is not the same as what we did to release specific REST-based cmdlets (see Get-ExchangeOnline* cmdlets listed here). This new work (enabling cmdlets to run without WinRM basic auth on a local client machine) is simply enabling regular cmdlets to run without WinRM basic auth. Therefore, you should not expect significant performance increases based on this work, as the goal is to not change any cmdlet names or change parameters, but to begin enabling all cmdlets to run without WinRM basic auth.

Installing the Preview Module

You can use the following command to install the preview module in PowerShell Core:

Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.6-Preview6 -AllowPrerelease

To Install on native PowerShell you will need to install the latest Package Manager and the latest version of PowerShellGet. To do this, close all PowerShell Windows and from an elevated PowerShell session, run the following command.

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -Force
Install-Module -Name PowerShellGet -Force -AllowClobber

Restart PowerShell and then you can install the module.

If you still have issues, you can download the latest version manually and copy it into the module folder by running:

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Save-Module -Name PowerShellGet -Path C:\LocalFolder -Repository PSGallery

Then copy all contents from under C:\LocalFolder into C:\Program Files\WindowsPowerShell\Modules. Restart PowerShell and then you can install the module.

Viewing the list of updated cmdlets

To generate the list of cmdlets that we have updated, please do the following:

Get-Command -Module tmpEXO*

This will create a list of all currently available updated cmdlets. Please note that due to preview status of this module (and related cmdlets) there might be situations that a specific cmdlet might be available one day and then becomes unavailable (if an issue is found, we would make it unavailable until the issue is resolved). That is why we suggest generating the cmdlet list by yourself when needed.

Let us know what you think! Send your product improvement suggestions and feedback to exocmdletpreview(AT) Remember this is a preview and we plan to continue adding more cmdlets to the list of those able to run without WinRM basic auth. As we make progress, we will make more announcements!

The Exchange Team

Brass Contributor

Noice !

Any plans to move the legacy CmdLets like Get-DistributionGroupMember etc. over to Get-ExoDistributionGroupMember (i.e. REST-based CmdLets)? ...


Or is there a plan to add the administration capabilitys to Graph and just have everyone go that way?


Love your work !

Brass Contributor

Finally, a module that works properly on MacOS as well. :)

Now, that it doesn't use basic auth anymore, the legacy commands are working as well, not only the Verb-EXO* cmdlets. So you can do Get-Mailbox as well as Get-EXOMailbox.

We can now use PowerShell core on more OSes. (not that I don't like Windows, I do, a lot)

@DevOpsMaverick The focus of this particular work is to move the existing cmdlets to not require WinRM basic auth... but this is not the same thing as making them into "Get-EXO*" cmdlets. It is not planned to move all of the Exchange cmdlets into full-REST "Get-EXO*" model, rather move them all to nor require WinRM basic auth.

Steel Contributor


I am a little bit curious. I am using

- Windows 11 

- PowerShell 5.1

- ExchangeOnlineManagement 2.0.5


Basic Auth in WinRM is already set to false and everything works fine as far as i see. Did the Support for Basic=False alredy come with a prior Module?


C:\>winrm get winrm/config/service
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false
Basic = false
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
AllowRemoteAccess = true


Regards Andres

Steel Contributor

Can you please clarify what these changes mean for the Verb-EXO*** cmdlets?  Are those still superior in terms of reliability in long-running scripts?  Or are all Verb-EXO*** cmdlets and all REST-API backed original cmdlets now equal?


I'm running into some shortcomings with Get-EXOMailbox / Get-EXORecipient but have things on the go today that I would like to develop unattended scripts for.  This would be for clients, so I want to go with the most 'legit' thing going (that will actually work).


I can do Get-EXOMailbox -ResultSize Unlimited, then Get-EXOMailboxStatistics, then do Get-Mailbox (legacy/ v2.0.5) for just a few mailboxes to get the properties I need, but were missed in the creation of Get-EXOMailbox.  Or, I can just jump to the preview module and use REST-API-backed Get-Mailbox / Get-MailboxStatistics.  But is one more reliable than the other in a 40K+ mailboxes EXO tenant?


*Edited to remove whiny-boo-boo closing.

Iron Contributor

@Jeremy Bradshaw what they basically did was rather than do a PSSession directly, made a rest API that calls a "Command" endpoint that issues the command on your behalf and returns CLIXML back that gets re-hydrated. Pretty clever way to maintain compatibility.


It's all just a wrapper around Invoke-WebRequest, which means that it can be parallelized and isn't subject to the 3 connection limit:
Justin Grote on Twitter: "I found a way to make the new #Exchange #Powershell commands work in paral...

Brass Contributor

@The_Exchange_Team : While this certainly is a nice development, in my understanding, "preview" modules are not supported, right? So why does the current, productive ExchangeOnlineManagement module in version 2.0.5 now bug me when calling any cmdlet to update to the newest module, when this newest module (apparently 2.0.6-preview5) is still just a preview?


There are other places in the Azure / PowerShell universe where it is the same: "use the preview module, or this won't work". You would never tell a customer to use the Outlook Beta to do some dedicated productive task, right? So why is this ok for admins? Or is there some basic part I don't understand about this?


Best regards

Copper Contributor

I agree with Sascha.

Even though I am excited to start working with this new version, as long as it's in preview, I will not install it yet for the same reason Sascha listed above.




Brass Contributor

I also agree, it's out of the question to use preview versions in our production environment. 

Please remove the warning or make version 2.0.6 GA.

Brass Contributor

Agree with the other posters above - turn off the warning until this is GA and fully supported.  "Please note that due to preview status of this module (and related cmdlets) there might be situations that a specific cmdlet might be available one day and then becomes unavailable" - sorry, I have an organization to run that relies on this functionality, I need something reliable and fully supported.

Brass Contributor

Same, telling people to upgrade to a module that is not GA is only going to cause those without experience dealing with the challenges of a preview build to get some experience in critical thinking and not just doing something because something told you to.

Copper Contributor

Will calling the REST API directly be documented? I have a scenario where I need a web site to run EXO PowerShell commands on behalf of a customer. We can't use the module because it wants to pop up a browser to authenticate the user on the machine where it's running (which would be the web server), or alternatively use a certificate to authenticate which we also can't do for various reasons.

Brass Contributor

@inkybuck : I guess you can use the Graph API for most Exchange tasks. But it is quite a hassle to manually do all the authentication stuff (get a token, renew the token in time before it expires and so on) - I did this once when I didn't know about the other option. Instead of this, you can use the MS Graph Powershell SDK which does all the authentication complexities for you. But then you still need to authenticate against it, the same as you would for the ExO PS module (or for calling the Graph REST API directly). From my experience, using a certificate is a lot less complicated then you would think. This runs very smoothly for automated scripts in our environment now.

What do you think is hindering you from using that? It doesn't need to be a PKI-managed certificate, it's just a local "object" with a private key that has the public key configured in an Azure app that you then use as service principal for authentication. And the Azure app also gets the appropriate permissions configured. I did go through that learning curve last week - maybe I can help :-).

Copper Contributor

@SaschaSeipp We actually already use the Graph API for some things, but unfortunately it doesn't do everything we need, some things are only possible through PowerShell. (There are also things that are only possible through graph, which is why we use both.)

What prevents us from using a certificate is that it's not really suitable to our scenario. We make a product that scans email for phishing and other things. We need to add connectors, transport rules, and other configuration to the customer's Exchange Online tenant so that it will send the mail to us to be checked, and accept it back afterward. To do this, we have a web site that, originally, got the user's email address and password and used them to log into PowerShell, then made the necessary changes to their tenant. Now, it uses OAuth to get a token that can be used to log into PowerShell - but this is an undocumented method that I imagine my go away, since it sounds like the EXO PowerShell module is not using that method anymore.

The certificate method is unsuitable for two main reasons: First, using a certificate would mean that instead of just having the customer log in to our site with their Microsoft credentials, they would have to go to the Azure AD portal and set up the certificate, which would be rather more complicated especially for non-technical customers. Even if they can do it, it would create a huge amount more friction than just needing to log in, and would be a terrible customer experience compared to what we have now. Second, that would grant us the ability to log into PowerShell for their tenant permanently (unless and until they go remove the certificate setup from Azure AD). We don't want that, we just want to log into PowerShell for them this one time and do the setup needed for our product, and when we log out, not have any ability to log in again by ourselves (and therefore not have to protect a token or certificate that would let someone do that).

The certificate is great for the scenario it was intended for, running an unattended script. But that's not what we're doing. We want to interactively get a delegated permission to use PowerShell on a customer's tenant on their behalf.

Brass Contributor

@inkybuck : Ok, that is obviously more complex than I thought :-), and I agree that a certificate would not help here at all.

I didn't read the news as the OAuth login for ExO's PS module would go away, though. From all I see right now, I get the impression that MS at some point might want to replace all those dedicated PS modules with the Graph SDK, but I guess they are still very far from that goal, if it actually is one.

I get what you want to achieve with your product, and I understand the idea is to make it as comfortable as possible for your customers, but I can tell you from the point of view of a rather skeptical admin: I would never enter my internal credentials into a vendor's product for the approach that the system does some "blackbox magic" to set itself up. I would always want to know exactly what's happening there and very much prefer a checklist and a manual on how to do this setup on my own, so I really know what the system is doing in my environment. Maybe that's just me.. ;-).

The general MS approach to that I think would be that you create an Azure app with the needed permissions that customers can setup from the gallery, and once they have granted the access in their tenant, your app can do its thing. Unfortunately I think it is not possible currently to only acquire certain permissions for setup and remove them later on, at least not in an easy way. But I don't know enough about this topic to really be of help here.

Copper Contributor

The OAuth way of logging into Exchange remote PowerShell has always been undocumented, so I don't think they will make any kind of announcement about it going away. But previously the PowerShell module was using it, so I figured it wouldn't go away while that was the case. This new module doesn't need it, though, clearing the way for them to turn it off whenever they want. It uses WSMan and a variation of basic auth where you supply the OAuth token in place of the password, so when basic auth goes away it's not clear to me that it will continue working.

You're right, letting an automated tool change your settings is an issue for some customers, we give those customers a PowerShell script that they can examine and run themselves. However, many customers are nontechnical and just want to get the thing installed.

Unfortunately, for PowerShell the only (official) way to grant access to an Azure app is by setting up a certificate. For most things, like Graph, or even the undocumented OAuth way of accessing PowerShell, you can have a user grant "delegated" access. They log in through a Microsoft page (so you never have access to their password), which gives you a token that you can use to do things on their behalf while they are logged in, but you have no ability to get another token later by yourself. In this case there is no permission to remove later on, because the permission was only granted for while they are logged in. This is how our app works today.

Copper Contributor

Hi Team,

I am getting the below error when I try to install the module.. is there something wrong with my execution.


PS C:\WINDOWS\system32> Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.6-Preview6 -AllowPrerelease


Install-Module : Cannot process argument transformation on parameter 'RequiredVersion'. Cannot convert value "2.0.6-Preview6" to type "System.Version". Error: "Input string was not in a correct format." At line:1 char:64
+ ... Name ExchangeOnlineManagement -RequiredVersion 2.0.6-Preview6 -AllowP ...
+ ~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Install-Module], ParameterBindingArgumentTransformationExce
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Install-Module

Copper Contributor

Will the Rest APIs be shared and documented? With the current APIs we can't get/set settings for CASMailbox, audit configs, ststistics, permissions, etc.

Brass Contributor

@The_Exchange_Team As other people have mentioned here - but it yet to be answered, I think its appalling that you are making warnings pop up in Powershell on old versions of the Exchange EXO v2 commands you have added to a preview version (i.e get-accepted domains) - with no documented way of turning it off!


Unfortunately our Powershell scripts has to interact to Service Now automation systems that screen scrape. Meaning that these messages are now breaking our automation as the output is polluted with these warnings.


I now have the option to run production on a preview version where command can 'disappear for periods of time'. Or try and figure out a custom way of suppressing the message on 10 automations (nothing working so far).


What are you doing about this? Can you supply a way of suppressing these messages? There are enough people asking here.

Steel Contributor

@MrPink99 the PowerShell warning stream is what it is, and shouldn't be allowed to cause your program or script problems.  That's not playing by the rules.

While I do agree the warning is pre-mature because the preview version is all that there is currently, vs a GA version of what is being advertised, I don't think anyone writing PowerShell can be held accountable for their warnings done the proper way causing this kind of issue.  The issue is that you're doing screen scraping and if that can't handle PowerShell warnings then your solution is the one that is flawed.  It's not the Exchange Team's fault, as unfortunate (and unnecessary) as it is.


As far as I can tell the warning happens only once per session (per Connect-ExchangeOnline).  Maybe you can use that behavior to your advantage and put in a dudd command to force the warning to come and go, then get back to the task at hand in the script/app?

Steel Contributor

@Radhakrishnan G I believe you need to update PowerShellGet (or try using PowerShell 7.2 instead of Windows PowerShell).  To update PowerShellGet in Windows PowerShell 5.1:


**Run (Windows) PowerShell as admin**.  Then:

Install-Module PowerShellGet -Force -AllowClobber


Done.  Retry your failed command and you should be all set.

Copper Contributor

Able to Install after Install-Module PowerShellGet -Force -AllowClobber. Thank you so much @Jeremy Bradshaw 

Brass Contributor

The behaviour of the module in 2.0.6previews seem to have changed. If you do not use the -$UseRPSsession switch there is no session created that is detectable by get-pssession.

I can understand why this is. However lots of our automations running on 2.0.4, test that an EXO connection is still connected and active before using it:

$ExistingEXOSession = get-pssession | Where-Object {$_.ComputerName -eq "" -and $_.state -ne "Broken"}

However now on 2.0.6-preview that session does not exist. Is there a new command to check the connect-exchangeonline command session is still active, or is there different way of doing it?


In the latest preview release 2.0.6 preview 6, currently 4 REST cmdlets have been withdrawn - 

These are being worked upon for the fix. In the interim, one can use –UseRPSSession switch to access the RPS flavor of these cmdlets.


@MrPink99 - You can write to with the domain name ( and the other details of the issue, the team can help disable the warning message for you.


@MrPink99 We are currently working on a Get-ConnectionInformation cmdlet that will provide Get-PSSession like functionality for REST backed cmdlets. This will be available in the upcoming version of the module.

Copper Contributor

Set-UnifiedGroup is missing from 2.0.6-Preview6. We are connecting with credentials, not a certificate.

EDIT: Ah, confirmed they've been removed as mentioned here:

Steel Contributor

@abhisk Preview7 was released 3 days ago but the four missing unifiedgroup cmdlets are still not available. How long is it going to take for this to be fixed?

Copper Contributor

Exchange Product Team: Can we get a release page akin to this please, that details not only GA but preview versions too?

Brass Contributor



Just checking in to see if there have been any updates with Get-ConnectionInformation since my previous comment post. As it is causing us some issues in v3.0. Our scripts need to be able to check if the network connection to 365 is still active (still has network connectivity), so a property that checked this and reports true and false is all that is needed, in the same way that get-pssession had ‘broken’ or ‘active’. At present Get-ConnectionInformation still reports success, and runs successfully with output (because the token is valid), even if the local network connection is pulled.

Version history
Last update:
‎May 24 2022 08:59 AM
Updated by: