
Use PowerShell to manage Exchange Online
Its Master's Voice
In a PowerShell session, admins can configure settings for Exchange Online and on-premises Exchange servers in parallel. Therefore, hybrid environments also benefit from the scripting language's possibilities. In this article, I introduce you to managing Exchange Online.
To manage Exchange Online from a computer with PowerShell, the computer must have a cloud connection and the required PowerShell modules, unless you only want to administer Exchange Online without on-premises Exchange servers, in which case you would be working remotely across the board. If you want to work with on-premises Exchange servers in parallel, you need to install the latest version of the Exchange management tools on the appropriate computer.
Configuring Local Settings with PowerShell
To manage Exchange Online, the local execution policy for PowerShell must be set to RemoteSigned
instead of Restricted
. If it is set to Restricted
, PowerShell will not run any scripts. RemoteSigned
trusts the scripts required for a remote connection. The first step in managing Exchange Online with PowerShell is to set the execution policy accordingly. On Windows 10 computers, you do this by starting the PowerShell session with administrative privileges from the context menu.
Depending on the execution policy settings, PowerShell blocks unsigned scripts. You can use the Set-ExecutionPolicy
cmdlet to change the execution policy and Get-ExecutionPolicy
cmdlet to view it. For example, to customize the execution policy on a server or a computer, use the
Set-ExecutionPolicy RemoteSigned
command. The command
Set-ExecutionPolicy Unrestricted
disables the execution policy completely. However, this action is not recommended, because it means any script can be run. However, if certain scripts cause problems, you can test the various execution policy settings:
-
Restricted
: No scripts are permitted. -
AllSigned
: Only signed scripts are permitted. -
RemoteSigned
: Scripts need to be signed by a certificate authority, and it is the default setting for Windows Server 2016 and 2019. -
Unrestricted
: All scripts can be run.
PowerShell Core versus PowerShell
In parallel with the standard version of PowerShell, Microsoft offers the open source Core variant [1], a newly developed platform-independent version of the scripting language. PowerShell Core is based on .NET Core.
PowerShell Core 6.x can be installed on Windows computers with Windows 7 or higher, but the Core variant generally offers fewer functions than the full version of PowerShell. For example, it lacks extensions and options for accessing devices by Windows Management Instrumentation (WMI). Microsoft is constantly working on the Core version of PowerShell. The plan, in the long run, is that all PowerShell modules will be available in PowerShell Core 6.x. In the meantime, many tasks can be carried out with the Core version without problem. The current PowerShell 5.1 will be the last version to be developed only for Windows. Microsoft's primary goal is to make all new versions platform independent, and PowerShell 6.0 will become the standard version for new Windows systems.
PowerShell Core 6.x can be installed on Windows clients as well as servers running Windows Server 2008 R2 or later. To install PowerShell Core 6.x on Linux machines, you need Ubuntu (14.04 or 16.04), Debian 8, CentOS 7, Red Hat Enterprise Linux 7, openSUSE 42.1, or Arch Linux. For other distributions, Microsoft offers a separate installation package on GitHub. On macOS machines, you need at least macOS 10.12. Additionally, PowerShell Core 6.x can also run in Docker containers and on the Kali Linux security distribution.
Before you can install PowerShell Core 6, you have to install the .NET Core Framework [2] on the corresponding computer. As with the previous PowerShell 5.x version, PowerShell Core 6 supports get-command
to display the full command set, so you can quickly see which commands can be used. The command works on Windows, macOS, and Linux computers. Once PowerShell Core is installed on a Linux machine, for example, type:
sudo apt-get update sudo apt-get install -y powershell
In SSH sessions (e.g., with Putty), you can launch PowerShell with the powershell
command, which extends the capabilities of Linux computers if Windows servers are used on the network. Also, admins who are new to Linux can use familiar tools such as PowerShell to manage Linux servers.
To view the installed version, run the PowerShell $PSVersionTable
command. The Get-Variable ls*
command also displays information about the installed version. For a list of all modules with which the current version of the installed PowerShell is compatible, use:
Get-Module -ListAvailable
In the future, PowerShell will use SSH to establish remote connections. Currently, winrm
is used for this purpose. By way of example, to establish a remote session, type the command:
Enter-PSSession -Hostname <IP or FQDN> -Username <username> -SSHTransport
PowerShell also includes the PowerShell Integrated Scripting Engine (ISE). In the future, however, it is expected that a graphical user interface will be available for PowerShell Core 6, probably based on Visual Basic code. Like PowerShell Core, the development environment is available for free.
PowerShell Core is suitable for managing Exchange Online, as well. The big innovation since PowerShell Core v6.1 is the ability to integrate Windows modules. Because Microsoft is no longer actively pursuing the development of PowerShell (as opposed to PowerShell Core), removing obstacles to the introduction of PowerShell Core has become even more important. If you already have PowerShell Core installed and want to use the latest version, run
Invoke-Expression "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"
to update directly in PowerShell.
Opening a Connection to Exchange Online
Whether you use the traditional PowerShell or PowerShell Core to connect, and whether you use a graphical environment such as PowerShell ISE or Visual Studio Code, the connection process is the same. The first step is to store the credentials of an administrator who has the right to connect to Exchange Online in a variable:
$user = Get-Credential
Storing in a variable has the advantage that you can authenticate quickly, because you only have to insert the variable at the right place and then set up a session for Exchange Online. You will want to save the session in a variable, because it lets you import the session in an active PowerShell window:
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $user -Authentication Basic -AllowRedirection
If you don't see an error message, you can import the stored session into PowerShell or PowerShell Core with
Import-PSSession $session
and work with Exchange Online.
This command imports the Exchange Online management cmdlets into the session and makes them available. However, to manage Exchange Online with PowerShell permanently, you might want to use PowerShell ISE or the Visual Studio Code graphical user interface, which will give you more control and provide more tools.
Visual Studio Code
Visual Studio Code (VS Code) is not only a development environment but allows the use of shells such as PowerShell, the command line, and Linux Bash. This approach has several advantages: You can use multiple shells in a single window and thus manage Exchange Online with PowerShell, as well as Linux shells, and manage other services on the network in parallel with PowerShell.
VS Code [3] is available free of charge as open source software. The major platforms – Linux, macOS, and Windows – are supported. The source code editor is mainly used for developing web applications but can also be used for management tasks. Combined, VS Code and PowerShell Core give you a powerful administration tool for use across different operating systems, especially if you also work with cloud environments like Exchange Online. You can even author scripts and combine them with other programming languages.
Integrating VS Code into Windows is easy. Versions for Windows, Linux, and macOS are available on the VS Code page I referred to before [3]. The installation takes just a few seconds. After launching, VS Code is ready for use. In the Terminal menu option you can open the shells currently supported, including PowerShell and PowerShell Core. You also can start and use several sessions in parallel, switching between the different terminals in the window, which makes it easier to develop scripts. To create new terminals, simply click on the plus sign. Moreover, the various icons let you display several sessions next to each other. In command code, you run VS Code from within a PowerShell session. The ise
command opens PowerShell ISE from within a conventional session.
Extending VS Code
The Ctrl+P (Cmd+P on macOS) keyboard shortcut displays a search bar at the top. From here, you can install extensions for VS Code (Figure 1). For example, to install PowerShell, enter:
ext install powershell

When you click on an extension, its details appear on the right, and the extension is installed.
In VS Code you can specify which version of PowerShell you want to use. The settings can be found under File | Preferences | Settings (Code | Preferences | Settings on Macs) | Features | Terminals, where you decide which shell to use by default in Windows. If you store the PowerShell Core executable in C:\Program Files\PowerShell\6\ pwsh.exe
, a PowerShell Core session will launch automatically. You can also open a terminal window with PowerShell by pressing the PowerShell button on the left.
The advantage of VS Code is that more than one shell can be used as a terminal. Extensions are also available, with which several shells can be integrated. One well-known example is the Shell Launcher extension, which you install in the same way as PowerShell support. More information is available from the Microsoft Shell Launcher page [4].
Once connected to Exchange Online, you can use virtually the same cmdlets that are available in the Exchange Management Shell.
Managing Exchange Online with PowerShell
Entering Get-Command
displays a list of all commands available in PowerShell. The Exchange Management Shell additionally offers a comprehensive help feature. If you can only recall part of a command, the *
wildcard is a big help. For example, typing
Get-Command *mailbox
displays all cmdlets with mailbox at the end of their names. If the command you are looking for is not included, you can even use multiple placeholders (e.g., Get-Command *mailbox*
, which displays all commands in which the word mailbox occurs somewhere).
Once you find the cmdlet you want, PowerShell gives you more options. Almost all cmdlets occur as one of four types:
- The
New-
prefix creates something (e.g.,New-Mailbox
). - The
Remove-
prefix deletes something (e.g.,Remove-Mailbox
). - The
Set-
prefix modifies something (e.g.,Set-Mailbox
). - The
Get-
prefix retrieves information about an object (e.g.,Get-Mailbox
).
Of course, many other cmdlets are available in addition to these cmdlets, such as Start
, Stop
, Export
, and Import
. However, most management tasks are covered by the New
, Remove
, Set
, and Get
cmdlets. If you type only the command, either nothing happens at all, the cmdlet displays all of the objects in the organization, or it prompts you for the identity of the object. For example, the Get-Mailbox
cmdlet lists all the mailboxes in the organization. If you only want to edit a single object, you need to specify the name of the object. If you fail to do this, you either see an error message telling you which options are missing, which can be helpful, or the Exchange Management Shell gradually prompts you for the required options and creates the object (e.g., for New-Mailbox
).
The same applies to the other Set
, Remove
, and Get
cmdlets. However, if you prefer to type all the necessary information and options at the command line rather than typing them in one at a time when prompted, the Exchange Management Shell provides detailed help:
Help <cmdlet> Help <cmdlet> -Detailed Help <cmdlet> -Examples
The first cmdlet gives information about a cmdlet, and the second option gives more detailed information. The third options provides examples of a command. These Help
cmdlets work for all commands in the Exchange Management Shell.
To get information about objects, use Get-Cmdlets
. This information is far more complete in Exchange Management Shell than in Exchange Admin Center. With the |fl
option, you can format the output. Again, you can see how much information Exchange Management Shell provides. If you do not want to display all information but only individual parameters, you can arrange them after the |fl
option. To display only the display name, database, alias, and organizational unit (OU) for the mailbox thomas.joos@FIXME.int, use the command (cmdlets are not case sensitive):
Get-Mailbox thomas.joos@FIXME.int |fl DisplayName, Database, Alias, OrganizationalUnit
Instead of a formatted list (fl
), you could go for a formatted table (ft
).
Another option offered by Exchange Management Shell is to read the mailboxes within a mailbox store database. When you enter the Get-Mailbox
command to get a list of all mailboxes in the organization, you also see the server on which the individual mailbox is located and whether a limit has been entered that prohibits sending. The command
Get-Mailbox | Format-Table DisplayName, Database
lets you display mailboxes sorted by the mailbox database and display name.
Managing Office 365
In addition to managing Windows and Microsoft servers and Exchange Online with PowerShell, you can manage the other cloud services in Office 365 or Microsoft Azure. All commands can be executed in a single PowerShell session, and you do not have to use separate windows to manage local servers, Microsoft server applications, and cloud services. To manage Office 365 and Microsoft Azure, you do need to download and install additional modules on the server:
Install-Module -Name AzureAD
Next, install the Microsoft Online Services Sign-In Assistant [5] and the Office 365 management module:
Install-Module MSOnline
After you have installed the extensions, connect to your Office 365 account in PowerShell. To do this, use the Connect-MsolService
cmdlet. If PowerShell cannot find the module, use Import-Module MSOnline
to load it. In the window, use an administrator account to authenticate to Office 365, and then use
Get-Command *msol*
to view each cmdlet. In most cases of a failed logon to Office 365, you are experiencing problems with the logon wizard. If this happens, either install the latest version of the wizard or download the latest official version from the Office 365 site. Also, make sure you install the correct language and note that you cannot run multiple versions in parallel on one computer. You must always uninstall the previous version (with appwiz.cpl
) before you install the successor.
Office 365 Subscriptions
The Get-MsolDomain
cmdlet displays the domains used in your Office 365 subscription and their domain status. Get-MsolDomainVerificationDNS
queries domain data. You can use PowerShell to remove domains and define the default domain:
Set-MsolDomain -Name contoso.onmicrosoft.com -IsDefault
Once you have modified the default domain, you can delete any domains you no longer need:
Remove-MsolDomain -DomainName contoso.com
To view all the roles available for access in your Office 365 subscription, use Get-MsolRole
. Make sure the User Management Administrator role has additional rights for user management, such as password resets. Get-MsolUser
displays information about your users. For example, to display licensed users, type:
get-msoluser |ft UserPrincipalname, Displayname, *lic*
The -Autosize
option fits the table to the window. To manage a specific user's licenses use:
get-msoluser -userprincipalname "<UPN>" |select licenses, islicensed | fl
Licenses can also be assigned directly:
set-msoluserlicense -userprincipalname "<UPN>" -addlicenses "<license name>"
An exhaustive list of cmdlet capabilities is available online [6].
Managing Office 365 Users
In addition to the cmdlets already mentioned, other commands let you create, manage, or delete users in Office 365:
-
New-MsolUser
creates a new user and password (e.g.,New-MsolUser -UserPrincipalName "<email-address>" -DisplayName "<displayname>"
). -
Remove-MsolUser
deletes the user and releases the assigned licenses. In this way, the mailbox can be registered for another 30 days. -
Restore-MsolUser
restores the user's original status. This action works up to 30 days after the deletion. -
Set-MsolUser
customizes a user, changing their settings. -
Set-MsolUserPassword
changes a user's password.
To see all the cmdlets that manage users, use get-command *msoluser*
. You can also manage groups in Office 365 with PowerShell. To see those commands, type get-command *msolgroup*
.
Conclusion
In recent years, Microsoft has increasingly focused on the cloud and PowerShell, and companies are gradually following this lead. Online services such as Exchange and Office 365 can be managed through PowerShell, just like local servers, and the Exchange Management Shell has plenty of options.