Connecting to Office 365/Exchange


Last update: Version 2.29, June 3rd, 2020

Almost 3 years ago, I wrote an article on how to enhance the PowerShell Integrated Scripting Environment, or ISE. That seemed adequate for the Exchange admin back then, who would mostly connect PowerShell sessions to their on-premises environment, and occasionally a bit of Exchange Online.

Fast forward to 2015, most modern Exchange administrators not only require a connection – if any – to their Exchange on-premises environment, but likely to one or more of the Office 365 services as well, including Exchange On-Premises, Azure Active Directory, Exchange Online Protection, Microsoft Teams, Skype for Business Online, SharePoint Online, Azure Information Protection or Compliance Center.

All these services use a different PowerShell session, use a different endpoint FQDN, and in some cases require a locally installed PowerShell module. Likely common denominator is the credential used to access each of these services. So, tired of re-entering my credentials every time when switching from Exchange Online to Exchange Online Protection, I created a script with a set of functions to allow me connect to each individual Office 365 service or Exchange Online:

  • Connect-AzureActiveDirectory: Connects to Azure Active Directory
  • Connect-AIP: Connects to Azure Information Protection
  • Connect-ExchangeOnline: Connects to Exchange Online
  • Connect-ExchangeOnlinev2: Connects to Exchange Online using REST module
  • Connect-SkypeOnline: Connects to Skype for Business Online
  • Connect-EOP: Connects to Exchange Online Protection
  • Connect-ComplianceCenter: Connects to Compliance Center
  • Connect-SharePointOnline: Connects to SharePoint Online
  • Connect-MSTeams: Connects to Microsoft Teams
  • Get-Office365Credentials: Gets Office 365 credentials
  • Connect-ExchangeOnPremises: Connects to Exchange On-Premises
  • Get-OnPremisesCredentials: Gets On-Premises credentials
  • Get-ExchangeOnPremisesFQDN: Gets FQDN for Exchange On-Premises
  • Get-Office365Tenant: Gets Office 365 tenant name (SharePoint)
  • Set-Office365Environment: Configures Uri’s and region to use
  • Get-TenantID: Returns TenantID using previously used credentials
  • Update-Office365Modules: Updates supported Office 365 modules
  • Report-Office365Modules: Report on known vs online module versions

Note that functions and credentials used in the script are global, and in principle only need to be entered once per shell or ISE session. If you need different credentials, call Get-Office365Credentials again. User interaction is a very basic (Read-Host), but it does the job. The script will also detect if  any PowerShell module supporting Multi-Factor Authentication is installed. If so, you will be prompted if for using MFA when authenticating to workloads such as Exchange Online, Azure Active Directory, Microsoft Teams, Skype for Business Online or SharePoint Online.

During initialization, the script will detect the modules which are required for certain Office 365 services. When not installed, it will notify you, and provide a link where to obtain the PowerShell module. The related Connect function will not be made available. PowerShell is required to run this script, which is tested against version 5.1 (but should work with lower versions down to version 3).

The functions are contained in a script called Connect-Office365Services.ps1. You can call this script manually from your PowerShell session to make the functions available. However, more convenient may be to have them always available in every PowerShell or ISE session. To achieve this, you need to edit your $profile, which is a script which always starts when you start a PowerShell or ISE session. By default this file does not exist and you need to create it, including the path. Also note that the files for PowerShell and ISE are different, Microsoft.PowerShell_profile.ps1
and Microsoft.PowerShellISE_profile.ps1 respectively.

Now, of course you can copy and paste the functions from the script file to your own $profile. Better is to call the script from your $profile, as this allows you to overwrite the Connect-Office365Services.ps1 with updates. To achieve this, assume you copied the Connect-Office365Services.ps1 in the same location as your $profile, for example C:\Users\Michel\Documents\WindowsPowerShell. You can then make PowerShell and ISE call this script by adding the following line to the $profile scripts:

& “$PSScriptRoot\Connect-Office365Services.ps1”

Now when you start a PowerShell session, you might see the following:


This shows the default environment is targeted (AzureCloud), the Exchange Modern Authentication PowerShell module as well as other modules mentioned in the example are installed. When online version checking is enabled (OnlineModuleVersionChecks variable), a check will be performed against the online repository, e.g. PSGallery, and outdated modules will be reported, like the Skype for Business Online module in the example. It’s also possible to automatically update modules setting the variable OnlineModuleAutoUpdate.

When you load the script from ISE, it will show something similar. However, it will also detect ISE and make connect functions available through the Add-On menu:


Customize this script to your liking. For example, by default the script will not perform version checking of installed modules as it slows down loading. In this case, module versions are checked against a built-in ‘last known version’ table. If you want to perform online version checking, look up the line $local:OnlineModuleVersionChecks = $false in the script, and change $false to $true. Automatic updates can be toggled setting local:OnlineModuleAutoUpdate to $true. Note that for updating modules, you need to have administrator permissions on the local system.

You can download the script from GitHub.

Revision History
Revision information is embedded in the source.

Feedback is welcomed through the comments. If you got scripting suggestions, questions or want to report bugs, you can do this through GitHub or by using the contact form.

81 thoughts on “Connecting to Office 365/Exchange

  1. Pingback: IT/DEV Connections 2015 Wrap-Up | EighTwOne (821)

  2. Pingback: Fixing Well-Known Folders Troubles (Update) | EighTwOne (821)

  3. Hi Michel,
    Your script has been a great time-saver for me. I just added the latest version (5/30/17) to my profile and it keeps crashing with the ‘404’ error whenever it tries to load and connect to SkypeOnline. Happens with both the ‘connect-office365’ as well as ‘connect-skypeonline’ calls. The ‘all services’ command doesn’t go any further when it fails at Skype. I’m looking forward to seeing what we can do with the MFA side of this once I get past this. If I’m doing something wrong, pls advise. Thanks!


  4. Thanks, @Michael de Rooij, for your work on this. Huge Time Saver…

    Loaded all the modules but haven’t verified connectivity to each of them yet. Just wanted to let you know that I encountered the following error when initially running version 1.71, May 29nd, 2017

    Write-Warning : Cannot bind parameter ‘ErrorAction’. Cannot convert value
    “” to type
    “System.Management.Automation.ActionPreference”. Error: “Unable to match the identifier name to a valid enumerator name. Specify one
    of the following enumerator names and try again:
    SilentlyContinue, Stop, Continue, Inquire, Ignore, Suspend”
    At C:\Users\nic7298-nmdev\Documents\WindowsPowerShell\Connect-Office365Services.ps1:276 char:226
    + … ErrorAction ‘ …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Write-Warning], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.WriteWarningCommand

    I was able to circumvent the error easily enough by editing the script as follows:
    Line 270 Added $ErrorActionPreference = “SilentlyContinue”
    Line 272 Removed -ErrorAction SilentlyContinue
    Line 278 Added $ErrorActionPreference = “Continue”

    One other minor issue, to get the ADAzurePreview module to load, I had to use the following command.
    Install-Module -Name AzureADPreview -AllowClobber


    • Thanks for the feedback. That message is odd, I’m running the 1.71 myself (with AzureADPreview installed) from w10. You by any chance import the non-preview module as well (since you’re using AllowClobber)?


  5. Hi, I have been using this script for couple of months,
    I redownloaded the script Version 1.71 and I have noticed the “Add-Ons” is not showing up the options, I am using powershell ISE,
    Cheers, Imrul


    • Hold LShift during start up. When you want different behavior, change the line which reads:
      $local:CreateISEMenu = $psISE -and [System.Windows.Input.Keyboard]::IsKeyDown( [System.Windows.Input.Key]::LeftShift)

      $local:CreateISEMenu = $psISE


  6. Hi Michel, thanks for the script! I am now using it with the MultiFactorAuthentication and what I run in to is that when I run the connect function to connect to all, you do not immediately set the $global:Office365CredentialsMFA and thus the AzureAD connection is tried with the basic credentials object. I updated it to initially call that Get-Office365Credentials function that sets the $global:Office365CredentialsMFA, and then that works.

    What is a bit annoying with that MFA in Powershell is that for every connection that you make you need to authenticate again, and as far as I see the compliance-center powershell URI does not (yet) support MFA? Is that correct?
    Thanks for sharing!


    • Thanks for the heads up. Unfortunately, tokens cannot be reused across connecting to workloads atm. And yes, standard PowerShell remoting does no support ADAL (thus MFA), e.g. ‘legacy’ Exchange Online or Compliance Center.


  7. I receive the following error when starting the script:

    Exchange Multi-Factor Authentication PowerShell Module installed (version 16.00.1935.000)
    Import-Module : A parameter cannot be found that matches parameter name ‘FullyQualifiedName’.
    At C:\Users\lholstee\Downloads\Connect-Office365Services.ps1:287 char:17
    + Import-Module -FullyQualifiedName $local:ModuleName -Force
    + ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Import-Module], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

    any suggestions?


  8. Hello, when i connect to exchange online i get the following message:

    Cannot convert value “0” to type “System.Version”. Error: “Version string portion was too short or too long.”
    At D:\powershell\Connect-Office365Services.ps1:324 char:10
    + If ( (Get-Module -Name ‘Microsoft.Exchange.Management.ExoPowershe …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocation

    any help?


    • Thanks for feedback. Replace
      [System.Version]((Get-Module -Name ‘SkypeOnlineConnector’ -ListAvailable).Version.Build) -ge [System.Version]’16.0′ ))
      [System.Version]((Get-Module -Name ‘Microsoft.Online.Sharepoint.PowerShell’ -ListAvailable).Version.Build) -ge [System.Version]’16.0′ ))


  9. Pingback: PowerShell Scripts for Office 365

  10. Pingback: How to connect to Exchange Online PowerShell via ISE with MFA the correct way –

  11. Pingback: Episode 11 – Why you should use PowerShell with Office 365 | Steve Goodman's All About Office 365

  12. after adding your script to my profile, when the ISE loads it shows me Azure RMS module not detected, link: When i go to that link, I get a page not found.

    I found this statement “The AADRM module has moved to the PowerShell Gallery and is no longer available from the Microsoft Download Center.” on


    • Basic authentication can be fed credentials, Modern Authentication with MFA or ADFS not, and tokens between workloads can not be shared (each workload different dialog). Plus side, when using UserPrincipalName with Exchange w/MA for example it will reuse the current token, so you will see the dialog appear briefly.


  13. After authenticating to one service ( Connect-ExchangeOnline ) any time I attempt to connect to another service (Connect-MsolService) I get prompted to enter in credentials again, Any ideas?

    Also, when trying to connect to the compliance center I get the following error: “New-IPPSSession : The term ‘New-IPPSSession’ is not recognized as the name of a cmdlet, function, script file, or
    operable program.”


    • Connect-MSolService is the msol connect cmdlet; it doesn’t reuse credentials used to connect to other services (hence why you need to use the helper functions provided). Note that MFA might require reauthenticating as well, as tokens are not shareable for all workloads at the moment. Finally, not having New-IPSSession indicated you don’t have the Exchange Online MFA-enabled powershell module installed; you can’t connect to the SCC anymore using old-fashioned remote PS.


      • Thank you for the quick reply.
        Whats weird is I have the Microsoft Exchange Online Powershell Module installed and I can connect to Exchange online using Connect-EXOPSSession and can connect to the compliance center using Connect-IPPSSession and both work fine.

        The issue i am facing is when using the script and “Connect-ComplianceCenter” I am getting the “New-IPPSSession : The term ‘New-IPPSSession’ is not recognized” error.

        It prompts me for credentials and MFA and after approving the MFA I get that error.
        Thanks again for your assistance


  14. After updating to 1.98.1, i’m getting the following:
    Exchange Modern Authentication PowerShell Module installed (version 16.00.2433.000)
    It is highly recommended to update the ExoPSSession module to version 16.00.2440.000 or higher.
    I have gone into the EXO Admin center and redownloaded the module to support MFA, and I’m still getting this message. Is there something else I need to do?


  15. Pingback: Conditional Access in Outlook on the web for Exchange Online – Microsoft Threat Protection

  16. Hello Michel.
    This is my first attempt at using the script and I was able to set up the modules and got it to load. However, I keep getting an Access denied error when trying to connect to Exchange Online.

    ISE detected, adding ISE menu options
    Environment set to AzureCloud
    Azure Active Directory (v1) module installed (v1.1.183.17)
    Azure Active Directory (v2) module installed (v2.0.2.4)
    Azure Active Directory (v2 Preview) module installed (v2.0.2.5)
    Azure RMS module installed (v2.13.1.0)
    Skype for Business Online module installed (v7.0.0.0)
    SharePoint Online module installed (v16.0.8414.0)
    Microsoft Teams module installed (v0.9.6)
    SharePointPnP Online module installed (v3.5.1901.0)
    PS C:\Users\e0062539> Connect-ExchangeOnline
    Would you like to use Modern Authentication? (y/N) : y
    TenantID: Tenant ID removed for security reason
    Connecting to Exchange Online using with Modern Authentication ..
    New-ExoPSSession : The term ‘New-ExoPSSession’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
    included, verify that the path is correct and try again.
    At C:\Users\ExchangeAdmin\Documents\WindowsPowerShell\Connect-Office365Services.ps1:269 char:53
    + … $global:myOffice365Services[‘Session365’] = New-ExoPSSession -Connec …
    + ~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (New-ExoPSSession:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException


  17. Hello Michel. Please discard my previous comments.. I realized that I remove the Exchange online MFA module while cleaning up to install your script but missed to install it back. 🙂

    I was able to connect just fine using MFA with modern auth.

    Thanks for such an awesome tool.


  18. Thanks for the script Michel,

    Is there a way to get the script itself to check for new versions and update? – a challenge for you 🙂



  19. Pingback: Configuring PowerShell for Office 365 - Office 365 for IT Pros

  20. Wow. Great job on the script, I’ve trialled a few and this is by far the best, love the way it keeps the modern auth when connecting to different services.

    Quick question hopefully, is the Connect-AzureActiveDirectory command supposed to connect to v1 and v2 in one go? or just v2?


  21. Pingback: Connecting to Office 365/Exchange | EighTwOne (821) – JC's Blog-O-Gibberish

  22. Getting this exception in the latest version (2.13). Any thoughts?

    PS C:\Users\Username\Documents\WindowsPowerShell> .\Connect-Office365Services.ps1
    Connect-Office365Services v2.13
    Running on x64 operating system
    Online Checks: False, IsAdmin: True, InternetAccess:True
    Environment set to AzureCloud
    Exchange Modern Authentication PowerShell Module installed (version 16.00.3346.000)
    Exchange supporting ADAL module found (version 2.16.20422.1202)
    Found Exchange Online Management (v2) (v0.3374.4) module
    Found Azure Active Directory (v1) (v1.1.183.17) module
    Found Azure Active Directory (v2) (v2.0.2.52) module
    Found Azure Active Directory (v2 Preview) (v2.0.2.53) module
    Found Azure Information Protection (v1.0.0.1) module
    Found Skype for Business Online (v7.0.0.0) module
    Found SharePoint Online (v16.0.19404.0) module
    Cannot convert the “System.Object[]” value of type “System.Object[]” to type “System.Uri”.
    At C:\Users\Username\Documents\WindowsPowerShell\Connect-Office365Services.ps1:638 char:10
    + If ( !($local:Item[3]) -or ( Get-Module -Name (‘{0}’ -f $local:It …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

    Cannot convert the “System.Object[]” value of type “System.Object[]” to type “System.Uri”.
    At C:\Users\Username\Documents\WindowsPowerShell\Connect-Office365Services.ps1:638 char:10
    + If ( !($local:Item[3]) -or ( Get-Module -Name (‘{0}’ -f $local:It …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

    Found SharePointPnP Online (v3.10.1906.0) module
    Found PowerApps-Admin-PowerShell (v2.0.6) module
    Found PowerApps-PowerShell (v1.0.8) module
    Found MSGraph-Intune (v6.1907.1.0) module


  23. Looks like an extra URL in the Teams definitions are hanging it up.

    ‘Connect|Microsoft Teams|Connect-MSTeams|MicrosoftTeams|Microsoft Teams (GA)||1.0.3|’
    ‘Connect|Microsoft Teams|Connect-MSTeams|MicrosoftTeams|Microsoft Teams (Test)||1.0.18|’


  24. In 2.20 the Connect-ExchangeOnlinev2 doesn’t work for basic authentication. Looks like the connection string has -ConnectionUrl instead of -ConnectionUri and -Session instead of -PSSession. I fixed those and it works great now! Thanks as always for the awesome script.


  25. Hi Michael,
    The latest version of the script I copied from GitHub doesn’t appear to have a variable named OnlineModuleAutoUpdate. I assume this was replaced with the Update-Office365Modules command?


    • Yes, functionality has been replaced (per v2.10) by Update-Office365Modules, as feedback suggested people don’t want the ‘delay’ every time they start a session (and thus never used it). If you want it, you could call Update-Office365Modules in your profile after loading the Connect helper functions.


  26. Hey Michel, I’m unable to get the latest version (2.25) of the script to recognize that the Skype for Business Online module is installed. I uninstalled and reinstalled it with no change and Get-Module reports that it’s installed.

    Any ideas? Thanks!

    Connect-Office365Services v2.25
    Running on x64 operating system
    Online Checks:False, IsAdmin:True, InternetAccess:True
    Environment set to AzureCloud
    Exchange Modern Authentication PowerShell Module installed (version 16.00.3527.000)
    Exchange supporting ADAL module found (version 2.16.20422.1202)
    Found Exchange Online Management (v2) (v0.3582.0) module
    Found Azure Active Directory (v1) (v1.1.183.57) module
    Found Azure Active Directory (v2) (v2.0.2.76) module
    Found Azure Active Directory (v2 Preview) (v2.0.2.85) module
    Found Azure Information Protection (v1.0.0.1) module
    Skype for Business Online module not found (
    Found SharePoint Online (v16.0.8924.1200) module
    Found Microsoft Teams (GA) (v1.0.5) module
    Found Microsoft Teams (Test) (v1.0.21) module
    Found SharePointPnP Online (v3.19.2003.0) module
    Found PowerApps-Admin-PowerShell (v2.0.45) module
    Found PowerApps-PowerShell (v1.0.9) module
    Found MSGraph-Intune (v6.1907.1.0) module
    Found Microsoft.Graph (v0.1.1) module

    ModuleType Version Name ExportedCommands
    ———- ——- —- —————-
    Binary Microsoft.Exchange.Management.Ex… {Add-EXOClientTelemetryWrapper, New-EXOClientTelemetryFile…
    Manifest Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con…
    Manifest Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
    Script 1.4.5 PackageManagement {Find-Package, Find-PackageProvider, Get-Package, Get-Pack…
    Script 2.2.1 PowerShellGet {Find-Command, Find-DscResource, Find-Module, Find-RoleCap…
    Script 2.0.0 PSReadline {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS…
    Script SkypeOnlineConnector {Get-CsOnlinePowerShellAccessInformation, Get-CsOnlinePowe…


  27. Hello Michel,

    Whenever I try to connect to MSTeams and select “Y” to use Modern Auth, I keep getting a popup window after typing my username/password stating my Tenant ID isn’t found. This may happen if there are no active subscriptions for the tenant…

    Request Id: 144fa700-53bd-4f23-ae61-d5024ec04301
    Correlation Id: 6033fdde-d7ba-4086-920f-7068c6794007
    Timestamp: 2020-06-18T10:29:46Z
    Message: AADSTS90002: Tenant ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx’ not found. This may happen if there are no active subscriptions for the tenant. Check to make sure you have the correct tenant ID. Check with your subscription administrator.

    Any thoughts or what am I doing incorrectly?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.