title: Import Microsoft Exchange Online PowerShell Module
body: <p>Previously, I used to connect PowerShell to Windows Azure Active Directory and Exchange Online using the following BAT file:</p>
  
  <pre><code>@echo off 
  Powershell -noexit -Command "&amp; {
      $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;
  }"
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>According to Microsoft's TechNet article <a href="https://technet.microsoft.com/en-us/library/mt775114(v=exchg.160).aspx" rel="nofollow noreferrer">"Connect to Exchange Online PowerShell using multi-factor authentication"</a>, I need to (<strong>only using a Microsoft web browser</strong>, no less) install the "[Microsoft] Exchange Online [Remote] PowerShell Module".</p>
  
  <p>I have done so and confirmed that I can now connect PowerShell to Exchange Online using an MFA- / TFA-enabled administrator account.</p>
  
  <p>However, I want to incorporate the new PowerShell module into my original BAT file but I'm not sure whether it's possible because:</p>
  
  <ol>
  <li>Research has yielded nothing relevant.  </li>
  <li>The Start Menu entry <code>Microsoft Exchange Online Powershell Module</code> is a <code>APPREF-MS</code> / ClickOnce file that seemingly doesn't point to any local file.</li>
  <li>Command <code>Get-Module –ListAvailable</code> doesn't output anything that contains <code>EXOP</code>.  </li>
  </ol>
  
  <p>Can anyone advise?</p>
  
  <p>&nbsp;</p>
  
  <p><strong>Update 2017/09/08 10:10</strong>:</p>
  
  <p>I:</p>
  
  <ol>
  <li>Read that ClickOnce applications were stored in the folder <code>%localAppData%\Apps\2.0\</code>.</li>
  <li>Searched the folder <code>%localAppData%\Apps\2.0\</code> for <code>*.ps1</code>.</li>
  <li>Found the file <code>C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\CreateExoPSSession.ps1</code>.</li>
  <li>Searched the file <code>C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\CreateExoPSSession.ps1</code> for <code>Connect-EXOPSSession</code>.</li>
  <li><p>Found the lines:  </p>
  
  <pre><code>$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
          }
  </code></pre></li>
  <li>Searched the folder <code>%localAppData%\Apps\2.0\</code> for <code>microsoft.exchange.management.exopowershellmodule.dll</code>.</li>
  <li>Found the file <code>C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a\Microsoft.Exchange.Management.ExoPowershellModule.dll</code>.</li>
  <li>Copied all files from folder <code>C:\Users\%userName%\AppData\Local\Apps\2.0\N8Z7NPYM.QVD\BL0EGO2J.G5A\micr..tion_51a5b647dacf4059_0010.0000_5d32306b9385c20a</code> to folder <code>C:\windows\system32\WindowsPowerShell\v1.0\modules\Exo</code>.</li>
  <li><p>Executed commands:  </p>
  
  <pre><code>Import-Module "C:\windows\system32\WindowsPowerShell\v1.0\modules\Exo\Microsoft.Exchange.Management.ExoPowershellModule.dll"
  New-ExoPSSession
  </code></pre></li>
  <li><p>Authenticated via MFA.</p></li>
  <li><p>Found that PowerShell ouputted the following:  </p>
  
  <pre><code> Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
   -- ----            ------------    ------------    -----         -----------------     ------------
    1 WinRM1          outlook.offi... RemoteMachine   Opened        Microsoft.Exchange       Available
  </code></pre></li>
  <li><p>Found that commands such as <code>Get-Mailbox</code> and <code>Get-InboxRule</code> were failing with the following errors:</p>
  
  <pre><code> %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
  </code></pre></li>
  </ol>
  
  <p>So, we're getting somewhere.</p>