Search code examples
powershelloffice365exchange-server

Import Microsoft Exchange Online PowerShell Module


Previously, I used to connect PowerShell to Windows Azure Active Directory and Exchange Online using the following BAT file:

@echo off 
Powershell -noexit -Command "& {
    $Credentials = Get-Credential;
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -Authentication Basic -ConnectionUri https://ps.outlook.com/powershell -AllowRedirection:$true -Credential $Credentials;
    Import-PSSession $Session;
    Import-Module MSOnline;
    Connect-MsolService -Credential $Credentials;
}"

This worked great until we enabled MFA / TFA on our global administrator accounts which then caused the above BAT file to fail with the following errors:

New-PSSession : [ps.outlook.com] Connecting to remote server ps.outlook.com failed with the following error message :
[ClientAccessServer=VI1PR0701CA0070,BackEndServer=amspr03mb326.eurprd03.prod.outlook.com,RequestId=f875eba9-7066-45df-9d59-67f9daf8b210,TimeStamp=9/7/2017 7:57:14 AM] Access Denied For more information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:66
+ ...  $Session = New-PSSession -ConfigurationName Microsoft.Exchange -Auth ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
    + FullyQualifiedErrorId : -2144108477,PSSessionOpenFailed
Import-PSSession : Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:1 char:256
+ ... ion:$true -Credential $Credentials; Import-PSSession $Session; Import ...
+                                                          ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Import-PSSession], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ImportPSSessionCommand

Connect-MsolService : Authentication Error: Authentication cancelled by user.
At line:1 char:290
+ ... Import-Module MSOnline; Connect-MsolService -Credential $Credentials}
+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [Connect-MsolService], Exception
    + FullyQualifiedErrorId : System.Exception,Microsoft.Online.Administration.Automation.ConnectMsolService

According to Microsoft's TechNet article "Connect to Exchange Online PowerShell using multi-factor authentication", I need to (only using a Microsoft web browser, no less) install the "[Microsoft] Exchange Online [Remote] PowerShell Module".

I have done so and confirmed that I can now connect PowerShell to Exchange Online using an MFA- / TFA-enabled administrator account.

However, I want to incorporate the new PowerShell module into my original BAT file but I'm not sure whether it's possible because:

  1. Research has yielded nothing relevant.
  2. The Start Menu entry Microsoft Exchange Online Powershell Module is a APPREF-MS / ClickOnce file that seemingly doesn't point to any local file.
  3. Command Get-Module –ListAvailable doesn't output anything that contains EXOP.

Can anyone advise?

 

Update 2017/09/08 10:10:

I:

  1. Read that ClickOnce applications were stored in the folder %localAppData%\Apps\2.0\.
  2. Searched the folder %localAppData%\Apps\2.0\ for *.ps1.
  3. Found the file C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\CreateExoPSSession.ps1.
  4. Searched the file C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\CreateExoPSSession.ps1 for Connect-EXOPSSession.
  5. Found the lines:

    $ExoPowershellModule = "Microsoft.Exchange.Management.ExoPowershellModule.dll";
    $ModulePath = [System.IO.Path]::Combine($PSScriptRoot, $ExoPowershellModule);
    
    $global:ConnectionUri = $ConnectionUri;
    $global:AzureADAuthorizationEndpointUri = $AzureADAuthorizationEndpointUri;
    $global:UserPrincipalName = $UserPrincipalName;
    $global:PSSessionOption = $PSSessionOption;
    
    Import-Module $ModulePath;
    $PSSession = New-ExoPSSession -UserPrincipalName $UserPrincipalName -ConnectionUri $ConnectionUri -AzureADAuthorizationEndpointUri $AzureADAuthorizationEndpointUri -PSSessionOption $PSSessionOption
    
    if ($PSSession -ne $null)
            {
                Import-PSSession $PSSession -AllowClobber
                UpdateImplicitRemotingHandler
            }
    
  6. Searched the folder %localAppData%\Apps\2.0\ for microsoft.exchange.management.exopowershellmodule.dll.
  7. Found the file C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\Microsoft.Exchange.Management.ExoPowershellModule.dll.
  8. Copied all files from folder C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a to folder C:\windows\system32\WindowsPowerShell\v1.0\modules\Exo.
  9. Executed commands:

    Import-Module "C:\windows\system32\WindowsPowerShell\v1.0\modules\Exo\Microsoft.Exchange.Management.ExoPowershellModule.dll"
    New-ExoPSSession
    
  10. Authenticated via MFA.

  11. Found that PowerShell ouputted the following:

     Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
     -- ----            ------------    ------------    -----         -----------------     ------------
      1 WinRM1          outlook.offi... RemoteMachine   Opened        Microsoft.Exchange       Available
    
  12. Found that commands such as Get-Mailbox and Get-InboxRule were failing with the following errors:

     %cmdlet% : The term '%cmdlet%' 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 line:1 char:1
     + %cmdlet%
     + ~~~~~~~~~~~
         + CategoryInfo          : ObjectNotFound: (%cmdlet%:String) [], CommandNotFoundException
         + FullyQualifiedErrorId : CommandNotFoundException
    

So, we're getting somewhere.


Solution

  • I was looking to do the same thing, and I came across this link. Simply running these two commands within a normal PowerShell window allowed me to connect to Exchange Online (with MFA-enabled):

    $CreateEXOPSSession = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -ErrorAction SilentlyContinue -Force | Select -Last 1).DirectoryName
    
    . "$CreateEXOPSSession\CreateExoPSSession.ps1"
    

    I could then connect using

    Connect-EXOPSSession