These steps allow you to connect to Exchange Online using PowerShell inside a Docker container from a Linux host. in my example I am connecting to Exchange Online from Ubuntu 21.04. For the Docker container image I am using the official Azure PowerShell container from Microsoft (mcr.microsoft.com/azure-powershell
).
The account I am using to administer Exchange Online has 2FA authentication enabled. Due to this I am using the -Device
authentication flag with Connect-ExchangeOnline
Update – 2022/05/07
At some point in the last few months, the original steps I published stopped working due to an SSL error:
PS /> Connect-ExchangeOnline -Device ---------------------------------------------------------------------------- The module allows access to all existing remote PowerShell (V1) cmdlets in addition to the 9 new, faster, and more reliable cmdlets. ....... To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXX to authenticate. pwsh: symbol lookup error: /opt/microsoft/powershell/7/libmi.so: undefined symbol: SSL_library_init
I have updated the below steps which resolve this problem. Installing the PSWSMan module and launching a new PowerShell session resolved the problem.
Container Setup
Start the container which will give you a PowerShell session:
docker run \ --rm \ -it mcr.microsoft.com/azure-powershell
It should look like this:
me@h4cktop ~ $ docker run \ --rm \ -it mcr.microsoft.com/azure-powershell PowerShell 7.1.3 Copyright (c) Microsoft Corporation. https://aka.ms/powershell Type 'help' to get help. PS />
Alternatively, if you will be reusing the container in future and don’t want to reinstall PSWSMan and the Exchange Online modules, create a container and attach to it:
docker container create -i -t \ --name powershell \ mcr.microsoft.com/azure-powershell docker container start --attach -i powershell
Next the PSWSMan module needs to be installed into the container. After installing the module a new PowerShell session needs to be started; without starting a new PowerShell session you will not be able to connect due to an SSL error.
Install-Module -Name PSWSMan -Force Install-WSMan pwsh
Next the PSWSMan
and
module needs to be installed inside the container:ExchangeOnlineManagement
Install-Module -Name ExchangeOnlineManagement -Force
The container should be setup and ready to connect to Exchange Online.
Exchange Online Connection
Now you can simply connect to Exchange Online using device authentication:
Connect-ExchangeOnline -Device
When you run the cmdlet you will be provided with an authentication code and a link to visit to enter the authentication code, as an example:
PS /> Connect-ExchangeOnline -Device ..... To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code 1234567XXX to authenticate.
Once you visit the link and authenticate/enter the code you should get a message in the web browser:
Wait for a few seconds and the PowerShell session should then be authenticated. Once authenticated you should get a message for “Creating implicit remoting module”:
Creating implicit remoting module ... Getting command information from remote session ... 150 commands received [ooooooooooooooooooooooooooooooooooooooooooooooooooooooo] 00:00:20 remaining.
The end result should look like this once authenticated:
PS /> Connect-ExchangeOnline -Device ---------------------------------------------------------------------------- The module allows access to all existing remote PowerShell (V1) cmdlets in addition to the 9 new, faster, and more reliable cmdlets. |--------------------------------------------------------------------------| | Old Cmdlets | New/Reliable/Faster Cmdlets | |--------------------------------------------------------------------------| | Get-CASMailbox | Get-EXOCASMailbox | | Get-Mailbox | Get-EXOMailbox | | Get-MailboxFolderPermission | Get-EXOMailboxFolderPermission | | Get-MailboxFolderStatistics | Get-EXOMailboxFolderStatistics | | Get-MailboxPermission | Get-EXOMailboxPermission | | Get-MailboxStatistics | Get-EXOMailboxStatistics | | Get-MobileDeviceStatistics | Get-EXOMobileDeviceStatistics | | Get-Recipient | Get-EXORecipient | | Get-RecipientPermission | Get-EXORecipientPermission | |--------------------------------------------------------------------------| To get additional information, run: Get-Help Connect-ExchangeOnline or check https://aka.ms/exops-docs Send your product improvement suggestions and feedback to exocmdletpreview@service.microsoft.com. For issues related to the module, contact Microsoft support. Don't use the feedback alias for problems or support issues. ---------------------------------------------------------------------------- To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code 1234567XXX to authenticate. PS />
You should now be able to run the Exchange Online cmdlets. As an example:
PS /> Get-EXOMailbox ExternalDirectoryObjectId : xxxxxxxx-e4e9-42bd-b2b7-xxxxxxxx UserPrincipalName : xxxxxxxx@gbe0.com Alias : xxxxxxxx DisplayName : xxxxxxxx EmailAddresses : {smtp:xxxxxxxx@gbe0.com} PrimarySmtpAddress : xxxxxxxx@gbe0.com RecipientType : UserMailbox RecipientTypeDetails : SharedMailbox Identity : xxxxxxxx Id : xxxxxxxx ExchangeVersion : 0.20 (15.0.0.0) Name : xxxxxxxx DistinguishedName : CN=xxxxxxxx,OU=xxxxxxxx.onmicrosoft.com,OU=Microsoft Exchange Hosted Organizations,DC=xxxxxxxx,DC=PROD,DC=OUTLOOK,DC=COM OrganizationId : xxxxxxxx.PROD.OUTLOOK.COM/Microsoft Exchange Hosted Organizations/xxxxxxxx.onmicrosoft.com - xxxxxxxx.PROD.OUTLOOK.COM/ConfigurationUnits/xxxxxxxx.onmicrosoft.com/Configuration Guid : xxxxxxxx-249d-42a3-9384-xxxxxxxx
In my case, I needed to enable DKIM for a newly added domain:
PS /> New-DkimSigningConfig -DomainName xxxxx.com -Enabled $true -KeySize 2048 PS /> Get-DkimSigningConfig xxxxx.com | Select-Object Selector1CNAME, Selector2CNAME | fl Selector1CNAME : selector1-xxxxx-com._domainkey.xxxxx.onmicrosoft.com Selector2CNAME : selector2-xxxxx-com._domainkey.xxxxx.onmicrosoft.com PS />
Potential Issues
While trying to get this work from other steps I found online I ran into a bunch of problems.
Unable to open a web page using xdg-open
On the first attempt at connecting using Connect-ExchangeOnline
I was getting an error that xdg-open couldn’t be used:
Error Acquiring Token: Unable to open a web page using xdg-open. See inner exception for details. Possible causes for this error are: xdg-open is not installed or it cannot find a way to open an url - make sure you can open a web page by invoking from a terminal: xdg-open https://www.bing.com New-ExoPSSession: /root/.local/share/powershell/Modules/ExchangeOnlineManagement/2.0.4/netCore/ExchangeOnlineManagement.psm1:475 Line | 475 | … PSSession = New-ExoPSSession -ExchangeEnvironmentName $ExchangeEnviro … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | One or more errors occurred. (Unable to open a web page using xdg-open. See inner exception for details. Possible causes for this error are: xdg-open is not installed or it cannot find a way to open an url - make sure you can open a web page by invoking | from a terminal: xdg-open https://www.bing.com )
This error was fixed by adding the -Device
flag to Connect-ExchangeOnline
.
WSMan client library was found
The next problem I ran into using the microsoft/powershell
container was that I managed to install the ExchangeOnline module and authenticate in my browser. After I authenticated, the Powershell session then gave this exception:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code 1234567XXX to authenticate. Exception: /root/.local/share/powershell/Modules/ExchangeOnlineManagement/2.0.4/netCore/ExchangeOnlineManagement.psm1:475 Line | 475 | … $PSSession = New-ExoPSSession -ExchangeEnvironmentName $E … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | This parameter set requires WSMan, and no supported WSMan client library was found. WSMan is either not installed or unavailable for this system.
The fix for this was to use the mcr.microsoft.com/azure-powershell
container instead.
2 thoughts on “Exchange Online PowerShell from Linux with Docker”
Hi can you show how to do this to an image?
Do you have more information about what you are trying to do? It’s possible the steps I provided no longer work; I will review them later and update if required.