IT

Operations guide

Exchange ServerOperations manual

Subscription Edition · 2019 · 2016
8 parts · 50 sections · 51 command blocks
Revised July 2026
/ per cercare

How to use this guide

This guide turns the official Microsoft documentation for Exchange Server (Subscription Edition, 2019 and 2016) into operational procedures you can use straight away. It does not replace the documentation: it makes it usable by someone who has just joined the team and has to work without breaking things.

Every section is marked with the minimum level of autonomy it requires. The level does not say how good you are, it says how much a mistake costs on that task.

LevelWhoWhat they can do aloneWhat they must escalate
L1Helpdesk / first lineReversible operations on single objects: creating mailboxes, groups, permissions, quotas, resetting client access, reading logs and queues.Any change to servers, databases, connectors, certificates, DAG.
L2Junior sysadmin / second lineMail flow diagnosis, queue management, receive connectors, ActiveSync policies, mailbox moves, planned routine maintenance.AD schema changes, CU updates, unplanned switchovers, restores from backup.
L3Senior / point of referenceEverything else: updates, DAG, disaster recovery, certificates, architecture.To Microsoft Support or the vendor.

At the start of every procedure you will find the level label. If you are reading a procedure above your level, read it anyway: it helps you understand what happens when you escalate. But do not run it.

#Typographic conventions

  • Text in carattere monospaziato is a command, a cmdlet name, a path or a value to be typed exactly as shown.
  • Grey blocks with a side bar are PowerShell commands to paste into the Exchange Management Shell.
  • Placeholders are written between angle brackets: <UserName>, <ServerName>. They must be replaced, brackets included.
  • Coloured boxes flag notes, warnings and prohibitions. Red warnings mean operations with potential data loss.

The ten golden rules

If you remember only one page of this guide, remember this one.

1. Read before you write

Every Get- cmdlet is safe and changes nothing. Every Set-, New-, Remove-, Enable-, Disable-, Move- cmdlet changes something. Before running a command that changes anything, run the matching Get- on the same object and look at how it is now.

2. Use -WhatIf

Almost every cmdlet that changes something accepts -WhatIf: it shows what it would do without doing it. On commands that hit more than one object (filters, pipes, loops) -WhatIf is not an option, it is a requirement.

Set-Mailbox -Identity m.rossi -ProhibitSendQuota 5GB -WhatIf

3. Distrust the pipe

Get-Mailbox | Set-Mailbox ... without a filter touches every mailbox in the organisation. It is the fastest way to cause an incident on this platform. Always filter, check the count, then run.

# 1) how many mailboxes would I hit?
(Get-Mailbox -ResultSize Unlimited -Filter "Department -eq 'Sales'").Count

# 2) simulation
Get-Mailbox -ResultSize Unlimited -Filter "Department -eq 'Sales'" | Set-Mailbox -IssueWarningQuota 4GB -WhatIf

4. One operation, one ticket

No change in production without a ticket that justifies it. Record in the ticket the exact command you ran, not a description in words. It is for you in three months, when somebody asks why that mailbox has that permission.

5. Disabling is not deleting

In Exchange the two words have precise and different technical meanings. Disabling detaches the mailbox from the AD user and keeps it for the retention period. Deleting removes both user and mailbox. If you are asked to "delete the mailbox of someone who has left", in 99% of cases the correct answer is to disable it or convert it to shared.

6. Quotas are not opinions

Before raising a user's quota, check the free space on the database volume. A database that fills the disk takes every mailbox it contains offline, not just the one belonging to the user who asked for more room.

7. Do not touch connectors to fix a single message

Receive and send connectors are shared infrastructure. A problem affecting one sender or one domain is almost always solved at the rule, recipient or reputation level, not by changing a connector.

8. Before any maintenance on a DAG member, maintenance mode

Restarting an Exchange server hosting active databases without putting it into maintenance mode means interrupting users and risking "lossy" activations. The procedure has its own page in this guide and consists of commands to be run in the order given.

9. Watch disk space and transaction logs

The number one cause of serious incidents on Exchange is not an attack: it is a volume full of transaction logs because the backup has stopped running. Check the space every day.

10. If you don't know, escalate. Immediately.

Escalating within ten minutes costs an hour of a colleague's time. Guessing for two hours on a database can cost the whole company a day's work. There is no shame in the first and no excuse for the second.

Part 1 — Fundamentals

L1L1 — required reading for everyone

#1.1 What Exchange Server actually is

Exchange Server is the system that receives, sorts, stores and delivers company mail, along with calendars, contacts and tasks. Three components to keep in mind:

  • The mailbox database: a file on disk (extension .edb) that physically holds users' mail, accompanied by the transaction logs. A server usually hosts more than one.
  • Transport: the part that accepts messages, evaluates them, routes them and delivers them. When "mail isn't arriving", the problem is almost always here.
  • Client access services: the front door for Outlook, phones and browsers. When "Outlook won't connect" but mail is flowing, the problem is almost always here.

From 2016 onwards these components live together in the same role, called Mailbox server. There is a second, optional role, the Edge Transport, installed in the DMZ without domain membership, acting as a perimeter filter towards the Internet.

#1.2 The tools you work with

ToolHow you open itWhat it is forLimitation
EAC — Exchange admin centerBrowser, address https://<server>/ecp90% of daily work on recipients, permissions, queues, certificates.Does not expose every parameter; some operations exist only in PowerShell.
EMS — Exchange Management ShellStart menu, on the server or on a workstation with the management toolsEverything. It is PowerShell with the Exchange cmdlets preloaded.No safety net: what you type gets executed.
Exchange ToolboxStart menu on the serverContains the Queue Viewer and the mail flow tools.On the server only.
Queue ViewerFrom the ToolboxSee and unblock transport queues through a graphical interface.Shows one server at a time.

#1.3 Anatomy of a command

Exchange cmdlets always follow the Verb-Noun structure, followed by parameters. Once you know the structure, the rest follows.

Set-Mailbox -Identity m.rossi -ProhibitSendQuota 5GB
  ^     ^         ^                 ^
  |     |         |                 valore
  |     |         parametro obbligatorio: quale oggetto
  |     su che tipo di oggetto agisco
  cosa faccio
VerbMeaningDanger
Get-Reads and showsNone. Use it freely.
Set-Changes an existing objectMedium. Overwrites the previous value.
New-Creates an objectLow, but creates a mess if you get it wrong.
Enable- / Disable-Enables or disables a featureMedium.
Add- / Remove-Adds or removes an item from a setMedium to high depending on the object.
Remove-Deletes an objectHigh. Often irreversible.
Move-Moves (mailboxes, active databases)High: it affects users while it runs.
Test-Runs a diagnosticNone.

The three switches you have to know

  • -WhatIf — simulates, does not run. Always use it the first time.
  • -Confirm:$false — suppresses the confirmation prompt. Do not use it until you are certain of the command: the prompt is there on purpose.
  • -ResultSize Unlimited — removes the default 1,000-result limit on reads. Without it, a Get-Mailbox on a large organisation shows you only part of the picture and you don't notice.

Making the output readable

# only the properties you need, as a table
Get-Mailbox m.rossi | Format-Table Name,PrimarySmtpAddress,Database -Auto

# every property of an object, as a vertical list
Get-Mailbox m.rossi | Format-List *

# export it to attach to the ticket
Get-Mailbox -ResultSize Unlimited | Export-Csv C:\Temp\mailboxes.csv -NoTypeInformation -Encoding UTF8

#1.4 The read-only commands to know by heart

These can be run at any time, even in the middle of an emergency, without asking anyone's permission.

CommandAnswers the question
Get-Mailbox <user> | flDoes this mailbox exist? Where is it? How is it configured?
Get-MailboxStatistics <user>How big is it? When did someone last connect to it?
Get-CasMailbox <user>Which client protocols are enabled on this mailbox?
Get-MailboxPermission <user>Who can open this mailbox?
Get-ADPermission <user>Who can send as this mailbox?
Get-QueueAre there messages stuck on this server?
Get-QueueDigest -Dag <DAG>Are there messages stuck on any server?
Get-MessageTrackingLogWhat happened to this message?
Get-ExchangeServerWhich servers are there, what version, what roles?
Get-MailboxDatabaseCopyStatus *Are the database copies healthy?
Get-ServerHealth <server>Does the server consider itself healthy?
Test-ServiceHealthAre all the required Exchange services running?

Part 2 — Mailboxes, groups and permissions

L1L1 — this is 70% of the daily work

#2.1 Recipient types

Before you create anything, pick the right type. Changing it later is possible but laborious, and by then users have already arranged themselves around the wrong object.

TypeWhen to use itDoes it have an active AD account?
User mailboxA person.Yes, with a licence and a password.
Shared mailboxA functional address used by several people: info@, support@, amministrazione@.The account exists but is disabled: access is by delegation.
Room mailboxA meeting room that can be booked from the calendar.Disabled account.
Equipment mailboxA bookable resource that is not a room: projector, company car.Disabled account.
Distribution groupAn address that forwards to a list of recipients.No, it is a group.
Mail-enabled security groupAs above, but it also grants permissions.No, it is a group.
Dynamic distribution groupThe member list is computed on the fly from a query (e.g. everyone in a department).No.
Mail contactAn external person who must appear in the address book.No.
Mail userA person with an internal account but an external mailbox (consultant, contractor).Yes, but without a local mailbox.

#2.2 Creating a user mailbox

L1L1

From EAC

  1. Recipients > Mailboxes > New user mailbox.
  2. Choose whether to create a new AD user or to enable an existing one. In most companies the AD user is created first by the onboarding process: in that case choose existing user.
  3. Fill in the alias and primary address according to the company naming standard. If you don't know it by heart, ask: renaming later leaves loose ends.
  4. Save and verify.

From EMS

# enable the mailbox on an AD user that already exists (most common case)
Enable-Mailbox -Identity "m.rossi" -Database "DB01"

# create AD user + mailbox in one go
New-Mailbox -Name "Mario Rossi" -Alias m.rossi -UserPrincipalName [email protected] `
  -FirstName Mario -LastName Rossi -Database "DB01" `
  -Password (ConvertTo-SecureString -String "<InitialPassword>" -AsPlainText -Force) `
  -ResetPasswordOnNextLogon $true

Check

Get-Mailbox m.rossi | Format-List Name,Alias,PrimarySmtpAddress,EmailAddresses,Database,RecipientTypeDetails

#2.3 Addresses and aliases

L1L1

A mailbox has one primary address (the one that appears as the sender) and any number of secondary addresses, all of which receive. In EmailAddresses the primary is written with an uppercase SMTP:, the secondaries with a lowercase smtp:.

# add an alias without touching the other addresses
Set-Mailbox m.rossi -EmailAddresses @{Add="[email protected]"}

# remove an alias
Set-Mailbox m.rossi -EmailAddresses @{Remove="[email protected]"}

# change the primary address, keeping the old one as secondary
Set-Mailbox m.rossi -EmailAddresses @{Add="[email protected]"}
Set-Mailbox m.rossi -PrimarySmtpAddress "[email protected]" -EmailAddressPolicyEnabled $false

#2.4 Storage quotas

L1L2L1 to read, L1/L2 to change according to internal policy

Quotas have three progressive thresholds.

ThresholdParameterEffect on the user
WarningIssueWarningQuotaGets a notification. Carries on working normally.
Send blockedProhibitSendQuotaCan no longer send. Still receives.
Fully blockedProhibitSendReceiveQuotaCan neither send nor receive. Senders get an NDR.

Quotas can be inherited from the database or set per mailbox. To set them per mailbox you have to disable inheritance explicitly.

# read the current state
Get-MailboxStatistics m.rossi | Format-List DisplayName,TotalItemSize,ItemCount,LastLogonTime
Get-Mailbox m.rossi | Format-List UseDatabaseQuotaDefaults,IssueWarningQuota,ProhibitSendQuota,ProhibitSendReceiveQuota

# set custom quotas
Set-Mailbox -Identity m.rossi -UseDatabaseQuotaDefaults $false `
  -IssueWarningQuota 9GB -ProhibitSendQuota 9.5GB -ProhibitSendReceiveQuota 10GB

# go back to the database values
Set-Mailbox -Identity m.rossi -UseDatabaseQuotaDefaults $true

#2.5 Mail forwarding

L1L1

Typical case: someone is away or has left the company and their mail has to go to a colleague.

# forward to an internal recipient, without keeping a copy
Set-Mailbox m.rossi -ForwardingAddress g.bianchi -DeliverToMailboxAndForward $false

# forward while keeping a copy in the original mailbox
Set-Mailbox m.rossi -ForwardingAddress g.bianchi -DeliverToMailboxAndForward $true

# forward to an external address (needs a contact or SmtpAddress)
Set-Mailbox m.rossi -ForwardingSmtpAddress "[email protected]" -DeliverToMailboxAndForward $true

# remove the forward
Set-Mailbox m.rossi -ForwardingAddress $null -ForwardingSmtpAddress $null

#2.6 Delivery restrictions and size limits

L1L1

# accept mail only from authenticated internal senders
Set-Mailbox communications -RequireSenderAuthenticationEnabled $true

# restrict who can write to a mailbox or a group
Set-DistributionGroup "All staff" -AcceptMessagesOnlyFromSendersOrMembers "Management"

# size limits per mailbox
Set-Mailbox m.rossi -MaxSendSize 35MB -MaxReceiveSize 35MB

#2.7 Permissions: the three delegations

L1L1 — by far the most frequent request

There are three distinct permissions and they get confused constantly, including by the people asking for them. Always clarify what is needed before granting them.

PermissionWhat it allowsWhat it does NOT allow
Full AccessOpening the mailbox, reading, creating, moving and deleting items.Sending messages from the mailbox.
Send AsSending messages that appear to come from the mailbox. The recipient sees no trace of the delegate.Reading the contents of the mailbox.
Send on BehalfSending messages with the sender shown as "Delegate on behalf of Mailbox". Replies go back to the mailbox.Reading the contents of the mailbox.

Full Access

Add-MailboxPermission -Identity "Assistenza Clienti" -User m.rossi `
  -AccessRights FullAccess -InheritanceType All

# without opening the mailbox automatically in the delegate's Outlook profile
Add-MailboxPermission -Identity "Assistenza Clienti" -User m.rossi `
  -AccessRights FullAccess -InheritanceType All -AutoMapping $false

# remove
Remove-MailboxPermission -Identity "Assistenza Clienti" -User m.rossi `
  -AccessRights FullAccess -InheritanceType All

# check
Get-MailboxPermission "Assistenza Clienti" | Where {$_.AccessRights -like "Full*"} |
  Format-Table -Auto User,Deny,IsInherited,AccessRights

Send As

Add-ADPermission -Identity "Assistenza Clienti" -User m.rossi -ExtendedRights "Send As"

# remove
Remove-ADPermission -Identity "Assistenza Clienti" -User m.rossi -ExtendedRights "Send As"

# check
Get-ADPermission -Identity "Assistenza Clienti" | Where {$_.ExtendedRights -like "Send*"} |
  Format-Table -Auto User,Deny,ExtendedRights

Send on Behalf

# replaces the list of delegates
Set-Mailbox "Assistenza Clienti" -GrantSendOnBehalfTo m.rossi

# adds without touching the others
Set-Mailbox "Assistenza Clienti" -GrantSendOnBehalfTo @{Add="[email protected]"}

# removes just one
Set-Mailbox "Assistenza Clienti" -GrantSendOnBehalfTo @{Remove="[email protected]"}

# works on groups too
Set-DistributionGroup "Ufficio Stampa" -GrantSendOnBehalfTo s.verdi

#2.8 Shared mailboxes

L1L1

# create
New-Mailbox -Shared -Name "Assistenza Clienti" -Alias support `
  -PrimarySmtpAddress [email protected]

# give access to a group
Add-MailboxPermission -Identity support -User "GRP-Assistenza" `
  -AccessRights FullAccess -InheritanceType All
Add-ADPermission -Identity "Assistenza Clienti" -User "GRP-Assistenza" -ExtendedRights "Send As"

# convert a user mailbox to shared (typical for someone leaving)
Set-Mailbox m.rossi -Type Shared

#2.9 Rooms and equipment

L1L1

New-Mailbox -Room -Name "Sala Consiglio" -Alias sala.consiglio
New-Mailbox -Equipment -Name "Proiettore 1" -Alias proiettore1

# automatic booking with no human approval
Set-CalendarProcessing "Sala Consiglio" -AutomateProcessing AutoAccept `
  -AllowConflicts $false -BookingWindowInDays 180 -MaximumDurationInMinutes 480 `
  -AddOrganizerToSubject $true -DeleteComments $false

# booking with approval by a delegate
Set-CalendarProcessing "Sala Consiglio" -AutomateProcessing AutoAccept `
  -AllBookInPolicy $false -AllRequestInPolicy $true -ResourceDelegates "s.verdi"

# capacity and location, useful in Outlook's room finder
Set-Mailbox "Sala Consiglio" -ResourceCapacity 12
Set-Place "Sala Consiglio" -Building "Sede centrale" -Floor 2 -Capacity 12

#2.10 Groups

L1L1

# plain distribution group
New-DistributionGroup -Name "Ufficio Acquisti" -Alias acquisti `
  -PrimarySmtpAddress [email protected] -Type Distribution `
  -OrganizationalUnit "contoso.it/Gruppi"

# mail-enabled security group (also used for permissions)
New-DistributionGroup -Name "GRP-Assistenza" -Type Security -Alias grp-support

# managing members
Add-DistributionGroupMember -Identity acquisti -Member m.rossi
Remove-DistributionGroupMember -Identity acquisti -Member g.bianchi
Get-DistributionGroupMember acquisti | Format-Table Name,PrimarySmtpAddress -Auto

# hide from the address book
Set-DistributionGroup acquisti -HiddenFromAddressListsEnabled $true

# allow only authenticated internal senders to write
Set-DistributionGroup "All staff" -RequireSenderAuthenticationEnabled $true

Dynamic groups

Members are not listed: they are computed at every send from a query on attributes. Useful for lists that follow the org chart, dangerous if the AD attributes are not kept clean.

New-DynamicDistributionGroup -Name "All - Rome office" -Alias all.rome `
  -RecipientFilter "(RecipientTypeDetails -eq 'UserMailbox') -and (Office -eq 'Roma')"

# ALWAYS CHECK who ends up in it, before announcing it
$g = Get-DynamicDistributionGroup "All - Rome office"
Get-Recipient -RecipientPreviewFilter $g.RecipientFilter | Format-Table Name,Office -Auto

#2.11 Recovery: deleted items and disconnected mailboxes

L1L2L1 for item recovery, L2 for reconnecting mailboxes

The user deleted a message and also emptied Deleted Items

It is not lost. It goes into the Recoverable Items folder, invisible to the user but accessible for the configured retention period (default: 14 days, often raised to 30).

  1. First solution, with no admin involved: in Outlook, Deleted Items folder, "Recover deleted items from server". In 90% of cases that is enough and no ticket is needed.
  2. If that is not enough, check the retention window: Get-Mailbox m.rossi | fl RetainDeletedItemsFor,SingleItemRecoveryEnabled
  3. If a targeted recovery is needed, escalate to L2: searching and restoring from Recoverable Items requires discovery permissions and has to be logged.
# extend the retention window (usually done at database level)
Set-Mailbox m.rossi -RetainDeletedItemsFor 30.00:00:00

# protect against permanent purges
Set-Mailbox m.rossi -SingleItemRecoveryEnabled $true

Disconnected mailboxes

When a mailbox is disabled or deleted, it stays in the database in a disconnected state for the retention period (default 30 days). Within that window it can be recovered.

# find the disconnected mailboxes on a database
Get-MailboxStatistics -Database DB01 | Where {$_.DisconnectReason -ne $null} |
  Format-Table DisplayName,DisconnectReason,DisconnectDate,MailboxGuid -Auto

# reconnect to an AD user
Connect-Mailbox -Identity "<MailboxGuid>" -Database DB01 -User "contoso\m.rossi"

#2.12 Disable, delete, convert

L1L1 with authorisation — read carefully

OperationCommandWhat happensReversible?
Convert to sharedSet-Mailbox <x> -Type SharedThe mail stays, access passes to the delegates.Yes.
DisableDisable-Mailbox <x>The mailbox detaches from the AD user and becomes disconnected. The AD user remains.Yes, within the retention period.
DeleteRemove-Mailbox <x>Removes both mailbox and AD account.Only within the retention period, and with difficulty.
Permanently deleteRemove-Mailbox <x> -Permanent $trueDestroys the data immediately.No. Never.

#2.13 Moving a mailbox between databases

L2L2

# start the move
New-MoveRequest -Identity m.rossi -TargetDatabase DB02 -BadItemLimit 10

# monitor it
Get-MoveRequest | Get-MoveRequestStatistics |
  Format-Table DisplayName,Status,PercentComplete,BytesTransferred -Auto

# clear completed requests (mandatory: they stay there forever)
Get-MoveRequest -MoveStatus Completed | Remove-MoveRequest

#2.14 PST import and export

L2L2 — requires dedicated permissions

The import/export cmdlets are not available by default even to organisation administrators: the role has to be assigned explicitly, for a specific reason. Anyone who can export mailboxes to PST can export anybody's mail.

# assign the role (L3 operation, one-off)
New-ManagementRoleAssignment -Role "Mailbox Import Export" -User "<administrator>"

# export
New-MailboxExportRequest -Mailbox m.rossi -FilePath "\\SRV-FILE\PSTExport\m.rossi.pst"

# export only a date range
New-MailboxExportRequest -Mailbox m.rossi `
  -ContentFilter {(Received -ge "01/01/2025") -and (Received -lt "01/01/2026")} `
  -FilePath "\\SRV-FILE\PSTExport\m.rossi-2025.pst"

# import
New-MailboxImportRequest -Mailbox m.rossi -FilePath "\\SRV-FILE\PSTImport\archivio.pst" `
  -TargetRootFolder "Archivio importato"

# monitor it e ripulire
Get-MailboxExportRequest | Get-MailboxExportRequestStatistics | ft DisplayName,Status,PercentComplete
Get-MailboxExportRequest -Status Completed | Remove-MailboxExportRequest

Part 3 — Clients, mobile devices, OWA

L1L2L1 for diagnosis and single-mailbox operations, L2 for server settings

#3.1 How a client connects, briefly

Understanding this sequence on its own solves half the "Outlook won't connect" tickets.

  1. Outlook looks for its configuration through Autodiscover: it queries the user's SMTP domain, looking for known records and URLs.
  2. Autodiscover replies with the service URLs: mailbox, availability, offline address book, and so on.
  3. Outlook connects through MAPI over HTTP, the default protocol in recent versions (it used to be Outlook Anywhere / RPC over HTTP).
  4. Authentication happens according to what is configured on the virtual directories (Integrated Windows, Basic, or modern authentication through ADFS in SE).

So: if Outlook won't connect but OWA works, the problem is almost always in Autodiscover, in the certificate or in the local profile. If OWA doesn't work either, the problem is further upstream: services, virtual directories, database or network.

#3.2 Enabling and disabling protocols per mailbox

L1L1

All client protocols are governed by the same cmdlet, Set-CasMailbox.

# snapshot of the situation
Get-CasMailbox m.rossi | Format-List Name,OWAEnabled,ActiveSyncEnabled,MAPIEnabled,PopEnabled,ImapEnabled,EwsEnabled

# disable
Set-CasMailbox m.rossi -ActiveSyncEnabled $false
Set-CasMailbox m.rossi -OWAEnabled $false
Set-CasMailbox m.rossi -PopEnabled $false -ImapEnabled $false

# re-enable
Set-CasMailbox m.rossi -ActiveSyncEnabled $true

# who still has POP/IMAP enabled (useful in a security review)
Get-CasMailbox -ResultSize Unlimited | Where {$_.PopEnabled -or $_.ImapEnabled} |
  Format-Table Name,PopEnabled,ImapEnabled -Auto

#3.3 Outlook on the web (OWA)

L1L2L1/L2

# state of the OWA virtual directories
Get-OwaVirtualDirectory | Format-List Server,Name,InternalUrl,ExternalUrl,*Authentication*

# OWA mailbox policies: what the user can do from a browser
Get-OwaMailboxPolicy | Format-List Name,*Enabled | Out-Host -Paging

# assign a policy to a mailbox
Set-CasMailbox m.rossi -OwaMailboxPolicy "Default"

#3.4 Mobile devices and ActiveSync

L1L1

Seeing what a user is carrying

Get-MobileDevice -Mailbox m.rossi | Format-Table FriendlyName,DeviceModel,DeviceOS,DeviceId,FirstSyncTime -Auto

Get-MobileDeviceStatistics -Mailbox m.rossi |
  Format-Table DeviceFriendlyName,DeviceModel,LastSuccessSync,Status,DevicePolicyApplied -Auto

Mobile device mailbox policies

They impose security requirements on the device: PIN, encryption, automatic lock, remote wipe capability.

Get-MobileDeviceMailboxPolicy | Format-List Name,PasswordEnabled,MinPasswordLength,MaxInactivityTimeLock,AllowSimplePassword,RequireDeviceEncryption

Set-CasMailbox m.rossi -ActiveSyncMailboxPolicy "Aziendale"

Device access rules

They decide whether a model or a device family is allowed, blocked, or quarantined pending approval.

Get-ActiveSyncDeviceAccessRule | Format-Table Characteristic,QueryString,AccessLevel -Auto

# explicitly allow a device family
New-ActiveSyncDeviceAccessRule -Characteristic DeviceModel -QueryString "iPhone" -AccessLevel Allow

# default behaviour for unclassified devices
Get-ActiveSyncOrganizationSettings | Format-List DefaultAccessLevel,AdminMailRecipients

Remote wipe

L1L1 only with explicit, documented authorisation

# 1) identify the device precisely
Get-MobileDevice -Mailbox m.rossi | Format-Table FriendlyName,DeviceModel,DeviceId,DeviceOS -Auto

# 2) wipe company data only (always the preferred option)
Clear-MobileDevice -Identity "<device Identity>" -AccountOnly `
  -NotificationEmailAddresses "[email protected]"

# 3) full device wipe (company-owned devices only)
Clear-MobileDevice -Identity "<device Identity>" `
  -NotificationEmailAddresses "[email protected]"

# remove the partnership after the wipe
Remove-MobileDevice -Identity "<device Identity>"

#3.5 POP3 and IMAP4

L2L2

Legacy protocols, still used by multifunction printers, business applications and appliances that have to read or send mail. They are also an attack surface: they almost always use basic authentication, which means credentials in the clear on the wire if TLS is not enforced.

# service state (they are disabled by default)
Get-Service MSExchangePOP3,MSExchangePOP3BE,MSExchangeIMAP4,MSExchangeIMAP4BE

# configuration
Get-PopSettings | Format-List Server,LoginType,UnencryptedOrTLSBindings,SSLBindings,X509CertificateName
Get-ImapSettings | Format-List Server,LoginType,UnencryptedOrTLSBindings,SSLBindings,X509CertificateName

# enforce TLS
Set-ImapSettings -LoginType SecureLogin
Set-PopSettings -LoginType SecureLogin

#3.6 Diagnostic tree: "the client isn't working"

L1L1 — follow it in order

QuestionIf YESIf NO
Does the problem affect a single user?Go to step 2.Jump to step 6: it is a service problem, not a user problem. Escalate.
2. Does OWA work for that user (https://<server>/owa)?The backend is healthy: it is a client or profile problem. Step 3.The mailbox or the service has a problem. Step 5.
3. Does it work from another PC, or in Outlook safe mode?Local problem: profile, OST cache, add-in. Recreate the profile.Step 4.
4. Does Get-CasMailbox <user> show the protocol as enabled?Check Autodiscover and the certificate: Test-OutlookWebServices -Identity <user>Re-enable the protocol and try again.
5. Does the mailbox respond? (Test-MapiConnectivity -Identity <user>)Check quotas and mailbox state.The database may be dismounted or failing over. Escalate to L2/L3.
6. Are the services up? (Test-ServiceHealth)Check queues, certificates and virtual directories. Escalate.Start the missing services if you are authorised, otherwise escalate immediately.
# the three diagnostic tests to keep handy
Test-ServiceHealth
Test-MapiConnectivity -Identity m.rossi
Test-OutlookWebServices -Identity m.rossi | Format-List Source,ServiceEndpoint,Scenario,Result,Error

Part 4 — Mail flow and troubleshooting

L2L1L2 — with some read-only diagnostics available to L1

#4.1 The transport pipeline in one page

Every message always goes through the same stages. Knowing which stage it stopped at is the diagnosis.

  1. Ingress. The message arrives through a receive connector (from the Internet, from an authenticated client, from an internal appliance) or is deposited by a local mailbox.
  2. Submission. It lands in the Submission queue, where the categorizer picks up the work.
  3. Recipient resolution. Exchange turns addresses into real recipients: it expands groups, applies forwards, resolves aliases.
  4. Routing. It decides where the message goes: local mailbox, another server in the organisation, send connector out to the Internet.
  5. Agents and rules. Mail flow rules (transport rules), journaling, DLP, antispam and antimalware are applied.
  6. Delivery. The message is deposited in the destination mailbox or queued towards the next hop.

#4.2 Message tracking: the number one tool

L1L1, read-only

Get-MessageTrackingLog answers the question you will be asked most often: "what happened to this email?". It requires the Microsoft Exchange Transport Log Search service to be running.

# latest entries on the local server
Get-MessageTrackingLog -ResultSize 100

# everything a sender sent within a time window
Get-MessageTrackingLog -ResultSize Unlimited `
  -Start "28/07/2026 08:00" -End "28/07/2026 18:00" `
  -Sender "[email protected]" |
  Format-Table Timestamp,EventId,Source,Recipients,MessageSubject -Auto

# failures only
Get-MessageTrackingLog -ResultSize Unlimited -Start "28/07/2026 00:00" -EventId FAIL |
  Format-Table Timestamp,Sender,Recipients,RecipientStatus -Auto

# search by subject
Get-MessageTrackingLog -ResultSize Unlimited -MessageSubject "Fattura 2026" | ft Timestamp,EventId,Sender,Recipients

The EventIds that matter

EventIdMeaningHow to read it
RECEIVEThe message came in.The Source field says where from: SMTP (network), STOREDRIVER (local mailbox), AGENT.
SENDIt was forwarded to the next hop.Outbound to another server or to the Internet.
DELIVERIt was delivered to a local mailbox.If this event is there, the message arrived. The problem is in the client.
FAILDelivery failed.Read RecipientStatus: it contains the SMTP code and the reason.
DEFERDelivery deferred, it will retry.Normal if occasional. If it persists, look at the queues.
DROPDropped without an NDR.Almost always a transport rule or the antispam.
RESOLVERecipient resolved to a different address.Alias, group or forward.
EXPANDDistribution group expanded.From here on there is more than one recipient.
TRANSFERSplit by bifurcation (content, different destinations).Normal.
POISONMESSAGEMessage deemed harmful to the service, isolated.Anomaly: escalate.

#4.3 Queues

L2L2

Looking

# non-empty queues on the local server
Get-Queue -Exclude Empty | Format-Table Identity,DeliveryType,Status,MessageCount,NextHopDomain -Auto

# aggregated view across all servers (the first command to run in an incident)
Get-QueueDigest -Dag <DAGName>
Get-QueueDigest -Forest

# queues above a given threshold
Get-Queue -Filter "MessageCount -gt 100" | Format-List

# what's inside a queue
Get-Message -Queue "<queue Identity>" | Format-Table Identity,FromAddress,Subject,Status,SCL,Size -Auto

Queue states

StateMeaningWhat to do
ActiveIt is delivering right now.Nothing. This is normal operation.
ReadyReady, waiting for resources.Nothing.
RetryThe connection to the next hop failed, it will retry at intervals.Check DNS, connectivity and the state of the destination. Then Retry-Queue.
SuspendedSuspended manually. No delivery.If you didn't suspend it, ask who did and why before resuming it.

Acting

# force a retry now (instead of waiting for the timer)
Retry-Queue -Identity "<queue Identity>"
Retry-Queue -Filter "Status -eq 'Retry'"

# resubmit messages to the categorizer (after routing or DNS changes)
Retry-Queue -Identity "<queue Identity>" -Resubmit $true

# suspend and resume
Suspend-Queue -Identity "<queue Identity>"
Resume-Queue -Identity "<queue Identity>"

# move a server's queues to another one (before maintenance)
Redirect-Message -Server SRV-EX01 -Target SRV-EX02.contoso.it

Acting on single messages

# suspend one specific message
Suspend-Message -Identity "<message Identity>"

# export a message to file for analysis (before removing it!)
$m = Export-Message -Identity "<message Identity>"
$m | AssembleMessage -Path "C:\Temp\message.eml"

# remove a message WITHOUT notifying the sender
Remove-Message -Identity "<message Identity>" -WithNDR $false

# remove all of a sender's messages from a queue (e.g. compromised account)
Get-Message -Queue "<queue Identity>" -Filter "FromAddress -eq '[email protected]'" |
  Remove-Message -WithNDR $false -Confirm:$false

#4.4 Connectors and accepted domains

L2L3L2 read-only, L3 for changes

# domains the organisation accepts as its own
Get-AcceptedDomain | Format-Table Name,DomainName,DomainType,Default -Auto

# receive connectors (who can deliver mail to us, and how)
Get-ReceiveConnector | Format-Table Server,Identity,Bindings,RemoteIPRanges,PermissionGroups -Auto

# send connectors (where we send outbound mail)
Get-SendConnector | Format-Table Name,AddressSpaces,SmartHosts,SourceTransportServers,Enabled -Auto

#4.5 NDR: reading the error message

L1L1

NDRs (Non-Delivery Reports) carry a three-level code. The first number says whether the problem is temporary or permanent.

CodeMeaningWho fixes it
4.x.xTemporary error. The server will retry.Nobody, if it clears. If it persists for hours: L2.
5.x.xPermanent error. The message will not go.Depends on the code.
5.1.1Recipient does not exist.The user got the address wrong. Check with Get-Recipient.
5.1.10Recipient not found in the directory.As above, often with an alias deleted recently.
5.2.2Recipient's mailbox full.The recipient, or L1 if internal (quota).
5.2.3Message too large.L1: check mailbox, connector and organisation limits.
5.4.1No route to the recipient.L2: routing, connectors, DNS.
5.7.1Rejected for authorisation or policy reasons.L2: relay permissions, delivery restrictions, rules.
5.7.606IP blocked by the recipient (often Microsoft 365).L3: delisting, IP reputation, SPF/DKIM/DMARC.

#4.6 Manual SMTP test

L2L2

Useful when you need to check whether a server answers and what it answers, without depending on a client or an application.

telnet mail.contoso.it 25

EHLO test.contoso.it
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: test connettivita

message body
.
QUIT

#4.7 Operational playbooks

L1L2L1/L2

Playbook A — "A user isn't receiving one specific email"

  1. Get the sender, the approximate time and the subject. Without at least two of the three, the search is impractical.
  2. Search the logs: Get-MessageTrackingLog -Start "<now-1h>" -End "<now+1h>" -Recipients "<user>" | ft Timestamp,EventId,Sender,MessageSubject
  3. If you find DELIVER: the message is in the mailbox. Check Outlook rules, the Junk folder and the Archive folder. The problem is not Exchange.
  4. If you find FAIL: read RecipientStatus, you already have the cause.
  5. If you find DROP: check transport rules and antispam. Get-TransportRule | ft Name,State,Priority
  6. If you find nothing: the message never reached the organisation. Have the sender check their own NDR. Then check the perimeter server's queues and any upstream filters.

Playbook B — "Nobody is receiving mail from outside"

  1. Immediate overview: Get-QueueDigest -Forest
  2. Services: Test-ServiceHealth on every server.
  3. Databases mounted: Get-MailboxDatabaseCopyStatus * | ft Name,Status,ContentIndexState
  4. Check that the public MX records point where they should and that port 25 is reachable from outside.
  5. Check the disk space on the volumes hosting queues and databases. A queue that won't drain because the disk is full is a recurring scenario.
  6. If the queues are growing but the services are up and the disk has room: escalate to L3. Do not restart services at random.

Playbook C — "An internal account is sending spam"

  1. Confirm: Get-Queue -Filter "MessageCount -gt 500" and Get-Message -Queue <queue> | group FromAddress | sort Count -Desc | select -First 5
  2. Stop the sending immediately: Set-Mailbox <user> -MaxSendSize 1KB or disable the account in AD according to the internal incident response procedure.
  3. Cut the mobile channels: Set-CasMailbox <user> -ActiveSyncEnabled $false -OWAEnabled $false
  4. Drain that user's outbound queue, exporting a sample first as evidence.
  5. Check whether a forward or a hidden mail rule has been set: Get-Mailbox <user> | fl Forwarding* and Get-InboxRule -Mailbox <user>
  6. Password change, session revocation, escalation to the security owner. Document times and actions.

Playbook D — "Mail to one specific domain won't go out"

  1. Look at the queue towards that domain: Get-Queue | Where {$_.NextHopDomain -like "*dominio.it*"} | fl
  2. Read LastError: it holds the remote server's text response, which often explains everything.
  3. Check DNS resolution of the MX records from the server: Resolve-DnsName dominio.it -Type MX
  4. Try a manual telnet connection to their MX on port 25.
  5. If the remote answer mentions reputation or a blacklist, escalate: requesting delisting is L3 work and has to be coordinated with whoever runs the public DNS.

#4.8 Antispam: the SCL scale

L1L1, read-only

Every message gets an SCL (Spam Confidence Level) score from 0 to 9. The thresholds decide what happens.

ThresholdParameterTypical behaviour
Junk folderSCLJunkThresholdDelivered but moved to Junk Email.
QuarantineSCLQuarantineThresholdDiverted to the quarantine mailbox, for review.
RejectSCLRejectThresholdRejected with an NDR to the sender.
DeleteSCLDeleteThresholdDiscarded silently. Nobody gets anything.
Get-ContentFilterConfig | Format-List SCL*Threshold,SCL*Enabled

# senders and domains always allowed / always blocked
Get-ContentFilterConfig | Format-List BypassedSenders,BypassedSenderDomains
Set-ContentFilterConfig -BypassedSenderDomains @{Add="fornitore-fidato.it"}

# per-mailbox antispam preferences
Get-MailboxJunkEmailConfiguration m.rossi | fl Enabled,TrustedSendersAndDomains,BlockedSendersAndDomains

Part 5 — Maintenance, high availability and updates

L2L3L2 for monitoring, L3 for operations. A junior does not run these procedures alone the first time.

#5.1 Routine checks

Every day (10 minutes, L1)

CheckCommandAlarm threshold
Exchange services startedTest-ServiceHealthA single required service not started.
QueuesGet-QueueDigest -ForestQueues above a few hundred messages, or in Retry for hours.
Database copiesGet-MailboxDatabaseCopyStatus *Any state other than Mounted / Healthy.
Search indexsame output, ContentIndexState columnAnything other than Healthy.
Disk spaceGet-Volume on the DB and log volumesBelow 20% free: plan. Below 10%: act today.
Backup completedBackup product consoleA single failed backup. The logs are not truncated and the disk fills up.
# daily check, all in one go
Test-ServiceHealth | Format-Table Role,RequiredServicesRunning,ServicesNotRunning -Auto
Get-QueueDigest -Forest
Get-MailboxDatabaseCopyStatus * | Format-Table Name,Status,CopyQueueLength,ReplayQueueLength,ContentIndexState -Auto
Get-Volume | Where {$_.DriveLetter} | Format-Table DriveLetter,FileSystemLabel,
  @{n="LiberoGB";e={[math]::Round($_.SizeRemaining/1GB,1)}},
  @{n="Libero%";e={[math]::Round($_.SizeRemaining/$_.Size*100,0)}} -Auto

Every week (L2)

  • Overall health check: Get-ExchangeServer | Get-HealthReport -RollupGroup
  • DAG replication check: Test-ReplicationHealth
  • Certificate expiry check: Get-ExchangeCertificate | ft Thumbprint,Services,NotAfter,Subject -Auto
  • Review of active external forwards and of suspicious new Inbox rules.
  • Review of the administrator audit logs, if enabled.

Every month (L2/L3)

  • Check whether the latest cumulative and security update is available.
  • Restore test: a restore that has never been tested is not a backup, it is a hope.
  • Review of quotas and database growth.
  • Check of inactive mailboxes and of leavers not yet processed.

#5.2 Managed availability: reading health state

L2L2

Exchange monitors itself: probes collect data, monitors evaluate the state, responders attempt automatic corrective actions (restarting a service, recycling an application pool, and as a last resort restarting the server). Knowing how to read this system stops you intervening where the server is already fixing itself.

# overview per server
Get-HealthReport -Identity <ServerName>

# unhealthy health sets only
Get-HealthReport -Identity <ServerName> | Where {$_.AlertValue -ne "Healthy"} |
  Format-Table HealthSetName,AlertValue,ServerComponent -Auto

# detail of the monitors in a specific set
Get-ServerHealth -Identity <ServerName> -HealthSet <SetName> |
  Format-Table Name,AlertValue,HealthSetName -Auto

# aggregated view across the organisation or a DAG
Get-ExchangeServer | Get-HealthReport -RollupGroup
(Get-DatabaseAvailabilityGroup <DAGName>).Servers | Get-HealthReport -RollupGroup

#5.3 Databases and copies

L2L2, read-only

# list of databases and where they are active right now
Get-MailboxDatabase -Status | Format-Table Name,Server,Mounted,DatabaseSize,AvailableNewMailboxSpace -Auto

# state of every copy: the most important command in this section
Get-MailboxDatabaseCopyStatus * |
  Format-Table Name,Status,CopyQueueLength,ReplayQueueLength,ContentIndexState,ActivationPreference -Auto
ColumnWhat it meansHealthy value
StatusRole and health of the copy.Mounted on the active, Healthy on the passives.
CopyQueueLengthLogs generated on the active and not yet copied to the passive.Close to 0. High numbers = network or disk problem.
ReplayQueueLengthLogs copied but not yet applied to the database.Close to 0, except for deliberately lagged copies.
ContentIndexStateState of the search index.Healthy. If Failed, user searches do not work.
ActivationPreferencePreference order for activation.1 = preferred copy.

DAG replication check

Test-ReplicationHealth -Identity <ServerName>

# across all members
(Get-DatabaseAvailabilityGroup <DAGName>).Servers | ForEach-Object { Test-ReplicationHealth -Identity $_.Name }

The test checks a series of components: replication service, Active Manager role, listener, member reachability, cluster networks, quorum group, file share witness, database redundancy and availability, presence of suspended, failed or seeding copies. Any outcome other than Passed has to be read item by item, not dismissed as a whole.

#5.4 Switchover: moving active databases

L3L2L3 — L2 only under an authorised procedure

A switchover is the planned move of activity from one server to another. A failover is the same move, but unplanned: the system decides it when something breaks.

# move all of a server's active databases, letting the system choose
Move-ActiveMailboxDatabase -Server SRV-EX01

# move to a specific server
Move-ActiveMailboxDatabase -Server SRV-EX01 -ActivateOnServer SRV-EX02

# move a single database
Move-ActiveMailboxDatabase DB01 -ActivateOnServer SRV-EX02

# simulate first
Move-ActiveMailboxDatabase -Server SRV-EX01 -WhatIf

#5.5 Maintenance mode on a DAG member

L3L3 — run it in order, without skipping steps

This is the procedure to learn by heart before touching any clustered Exchange server: updates, restarts, hardware work, Windows patches. It takes the server out of production in an orderly way, without interrupting users and without losing messages in transit.

Phase 1 — Entering maintenance

# 1. drain the transport queues
Set-ServerComponentState <ServerName> -Component HubTransport -State Draining -Requester Maintenance

# 2. apply the drain
Restart-Service MSExchangeTransport

# 3. (Exchange 2016 with unified messaging only)
Set-ServerComponentState <ServerName> -Component UMCallRouter -State Draining -Requester Maintenance

# 4. go to the Exchange scripts folder
CD $ExScripts

# 5. move active databases and critical roles elsewhere, and pause the cluster node
.\StartDagServerMaintenance.ps1 -ServerName <ServerName> -MoveComment Maintenance -PauseClusterNode

# 6. redirect the messages still queued to another server
Redirect-Message -Server <ServerName> -Target <FQDN other server>

# 7. take the server fully offline as far as the services are concerned
Set-ServerComponentState <ServerName> -Component ServerWideOffline -State Inactive -Requester Maintenance

Phase 2 — Verifying it really is in maintenance

# only Monitoring and RecoveryActionsEnabled should read Active
Get-ServerComponentState <ServerName> | Format-Table Component,State -Autosize

# no active database can be activated here
Get-MailboxServer <ServerName> | Format-List DatabaseCopyAutoActivationPolicy   # atteso: Blocked

# cluster node paused
Get-ClusterNode <ServerName> | Format-List

# queues empty
Get-Queue

Only when all four checks give the expected result can you proceed with the work: update, restart, hardware replacement.

Phase 3 — Returning to production

# 1. bring the server back online
Set-ServerComponentState <ServerName> -Component ServerWideOffline -State Active -Requester Maintenance

# 2. (Exchange 2016 with unified messaging only)
Set-ServerComponentState <ServerName> -Component UMCallRouter -State Active -Requester Maintenance

# 3.
CD $ExScripts

# 4. resume the cluster node, unblock activation, resume the copies
.\StopDagServerMaintenance.ps1 -ServerName <ServerName>

# 5. re-enable transport
Set-ServerComponentState <ServerName> -Component HubTransport -State Active -Requester Maintenance
Restart-Service MSExchangeTransport

# 6. final check
Get-ServerComponentState <ServerName> | Format-Table Component,State -Autosize
Get-MailboxDatabaseCopyStatus * | ft Name,Status,CopyQueueLength,ContentIndexState -Auto

# 7. optional: rebalance the active copies according to preference
.\RedistributeActiveDatabases.ps1 -DagName <DAGName> -BalanceDbsByActivationPreference -Confirm:$false
Set-ServerComponentState <ServerName> -Component ServerWideOffline -State Active -Requester Functional
Set-ServerComponentState <ServerName> -Component Monitoring -State Active -Requester Functional
Set-ServerComponentState <ServerName> -Component RecoveryActionsEnabled -State Active -Requester Functional

#5.6 Cumulative and security updates

L3L3

Every cumulative update (CU) is a full installation of the product: you do not need to install the previous CUs in sequence. Security updates (SU), on the other hand, apply to one specific CU.

Preparation, in order

  1. Read the release notes for that specific CU. Every CU has its own surprises.
  2. Check system requirements and prerequisites: they may have changed since the CU you have installed.
  3. Check whether the CU requires Active Directory schema updates or domain preparation. If it does, you need elevated permissions and a dedicated window.
  4. Run and verify a working backup of Active Directory and of Exchange.
  5. Save every customisation separately: web.config and EdgeTransport.exe.config files, TLS settings and operating system cryptography. They get overwritten.
  6. Test in a non-production environment, if you have one.
  7. Restart the server before you start, to clear any pending reboots.
  8. Temporarily disable the antivirus for the duration of the installation.
  9. If the server is a DAG member, put it into maintenance mode (§5.5).
  10. Run the setup program from an elevated prompt.

Indicative time stated by the documentation for a CU update: about three hours per server. Plan the window accordingly, and across multiple servers work in sequence, never in parallel.

# check the installed version and build
Get-ExchangeServer | Format-Table Name,Edition,AdminDisplayVersion,ServerRole -Auto

# more precise build check
Get-Command ExSetup.exe | ForEach {$_.FileVersionInfo}

#5.7 Certificates

L3L1L2L3 — L1/L2 must be able to read them and know when they expire

# list of certificates with expiry and assigned services
Get-ExchangeCertificate | Format-Table Thumbprint,Services,NotAfter,Subject,CertificateDomains -Auto

# which ones expire in the next 60 days
Get-ExchangeCertificate | Where {$_.NotAfter -lt (Get-Date).AddDays(60)} |
  Format-Table Thumbprint,Subject,NotAfter,Services -Auto

In the Services column the letters show which services the certificate is assigned to: IMAP, POP, UM, IIS (web), SMTP. An expired certificate assigned to IIS blocks OWA, ECP, ActiveSync and Outlook connectivity for everyone, all at once.

#5.8 Backup and restore

L3L3

Exchange supports backup through VSS. A successful full backup truncates the transaction logs: that is the mechanism that stops the volumes filling up. A backup that fails silently for days is the prelude to a full disk and dismounted databases.

  • Full backup: copies databases and logs, then truncates the logs. This is the one you need.
  • Incremental backup: copies only the logs since the last backup and truncates them.
  • Copy backup: copies without truncating. Useful for occasional extractions, useless for log hygiene.

Recovery database

A recovery database lets you mount a restored copy of a database alongside production, to extract data without touching the live mailboxes. It is the correct mechanism for answering "we need that mailbox's mail as it was last month".

New-MailboxDatabase -Recovery -Name RDB01 -Server <ServerName> `
  -EdbFilePath "E:\RDB01\DB01.edb" -LogFolderPath "E:\RDB01\Logs"

Mount-Database RDB01

# extract the contents into a folder of the destination mailbox
New-MailboxRestoreRequest -SourceDatabase RDB01 -SourceStoreMailbox "Mario Rossi" `
  -TargetMailbox m.rossi -TargetRootFolder "Ripristino 2026-07"

Get-MailboxRestoreRequest | Get-MailboxRestoreRequestStatistics | ft Name,Status,PercentComplete

#5.9 Disk space and transaction logs

L1L2L3L1 for monitoring, L2/L3 for intervention

Every change to a mailbox is written to a transaction log first and applied to the database afterwards. The logs pile up until a full backup truncates them. The usual causes of abnormal growth:

  • The backup is not running, or runs but fails, or is configured as a copy backup.
  • A bulk mailbox move or a large PST import in progress.
  • A runaway synchronisation loop from a client or an application.
  • A suspended or failed database copy preventing truncation in the DAG.
# how much each database takes up and how much white space it holds
Get-MailboxDatabase -Status | Format-Table Name,DatabaseSize,AvailableNewMailboxSpace,Mounted -Auto

# the 20 largest mailboxes: useful for seeing where growth is
Get-MailboxStatistics -Database DB01 | Sort-Object TotalItemSize -Descending |
  Select-Object -First 20 DisplayName,TotalItemSize,ItemCount,LastLogonTime

Part 6 — Quick reference

#6.1 Cheat sheet: from task to command

I need to...CommandLvl
See a mailbox's configurationGet-Mailbox <user> | flL1
See how big a mailbox isGet-MailboxStatistics <user>L1
Create a mailbox on an existing AD userEnable-Mailbox -Identity <user> -Database <DB>L1
Create a shared mailboxNew-Mailbox -Shared -Name "<Name>" -Alias <alias>L1
Add an aliasSet-Mailbox <user> -EmailAddresses @{Add="<address>"}L1
Grant Full AccessAdd-MailboxPermission -Identity <mailbox> -User <user> -AccessRights FullAccess -InheritanceType AllL1
Grant Send AsAdd-ADPermission -Identity <mailbox> -User <user> -ExtendedRights "Send As"L1
Grant Send on BehalfSet-Mailbox <mailbox> -GrantSendOnBehalfTo @{Add="<user>"}L1
Set quotasSet-Mailbox <user> -UseDatabaseQuotaDefaults $false -IssueWarningQuota ... -ProhibitSendQuota ...L1
Set up forwardingSet-Mailbox <user> -ForwardingAddress <recipient> -DeliverToMailboxAndForward $trueL1
Hide from the address bookSet-Mailbox <user> -HiddenFromAddressListsEnabled $trueL1
Convert to sharedSet-Mailbox <user> -Type SharedL1
Add to a groupAdd-DistributionGroupMember -Identity <group> -Member <user>L1
See a group's membersGet-DistributionGroupMember <group>L1
Disable ActiveSync for a userSet-CasMailbox <user> -ActiveSyncEnabled $falseL1
See a user's phonesGet-MobileDeviceStatistics -Mailbox <user>L1
Wipe company data from a phoneClear-MobileDevice -Identity <id> -AccountOnlyL1*
Search for a messageGet-MessageTrackingLog -Sender <sender> -Start <time> -End <time>L1
See the queues, all serversGet-QueueDigest -ForestL1
Force a delivery retryRetry-Queue -Filter "Status -eq 'Retry'"L2
Remove messages from a queueGet-Message -Queue <queue> -Filter ... | Remove-Message -WithNDR $falseL2
Move a mailbox between databasesNew-MoveRequest -Identity <user> -TargetDatabase <DB>L2
Export a mailbox to PSTNew-MailboxExportRequest -Mailbox <user> -FilePath <UNC>L2
Check the servicesTest-ServiceHealthL1
Check the database copiesGet-MailboxDatabaseCopyStatus *L1
Check DAG replicationTest-ReplicationHealthL2
Move a server's active databasesMove-ActiveMailboxDatabase -Server <server>L3
Put a server into maintenancesee §5.5, full procedureL3
Check the certificatesGet-ExchangeCertificate | ft Thumbprint,Services,NotAfterL1

#6.2 Ports to know

PortProtocolUsed by
25SMTPMail between servers and from the Internet. Receive connectors.
587Authenticated SMTPSending from authenticated clients and applications.
465SMTPSImplicit TLS submission, used by some appliances.
443HTTPSOWA, ECP, EWS, ActiveSync, MAPI over HTTP, Autodiscover, OAB. The port.
80HTTPOnly for redirection to HTTPS.
110 / 995POP3 / POP3SPOP clients.
143 / 993IMAP4 / IMAP4SIMAP clients.
2525Internal SMTPReceiving between internal transport services on the same server.
50636Secure LDAP (AD LDS)EdgeSync synchronisation towards Edge Transport servers.
64327SMTPRedundant transport between Mailbox servers.

#6.3 Critical services

ServiceIf it is stopped...
MSExchangeIS (Information Store)Nobody can get to their mail. The single most critical service.
MSExchangeTransportMail neither enters nor leaves the server.
MSExchangeFrontEndTransportThe server does not accept SMTP connections from outside.
MSExchangeRepl (Replication)DAG replication stops. The copy queues grow.
MSExchangeADTopologyPractically everything stops working: it is the base dependency.
MSExchangeMailboxAssistantRoom booking, retention policies and the various assistants stop.
MSExchangeTransportLogSearchMessage tracking logs can no longer be searched.
W3SVC (IIS)OWA, ECP, ActiveSync, Outlook: everything down.
# quick check, by role
Test-ServiceHealth | Format-Table Role,RequiredServicesRunning,ServicesNotRunning -Auto

#6.4 Escalation matrix

SituationWho handles itEscalate within
A user is not receiving an emailL1If the playbooks in §4.7 give you no cause: 30 min.
A user cannot get to their mailL1If OWA does not work: straight to L2.
Request for permissions, aliases, quotas, groupsL1Not escalated, just done.
Request to wipe a deviceL1 with authorisationIf the authorisation is not clear: do not run it, escalate.
A queue growing on a serverL2If it passes a few thousand messages or lasts over 1h: L3.
Internal account sending spamL1 blocks, L2 investigatesAt the same time as the block: immediately to L2 and security.
Database copy Failed or index FailedL2Straight to L3 if it concerns the only healthy copy.
Certificate about to expireL2At 60 days: plan with L3. At 7 days: emergency.
Dismounted databaseL3Immediate. Do not attempt Mount-Database on your own.
Full disk on a DB or log volumeL3Immediate.
General service outageL3Immediate, in parallel with collecting the state.

#6.5 Ticket annotation template

TICKET #.........        DATA/ORA: ..................
RICHIEDENTE: ..................  AUTHORISED BY: ..................

RICHIESTA (una riga):
..................................................................

OBJECTS INVOLVED (mailboxes, groups, servers):
..................................................................

CHECK BEFORE (command + brief output):
..................................................................

COMMAND RUN (verbatim, copy-paste):
..................................................................

CHECK AFTER (command + output):
..................................................................

REVERSIBLE?  [ ] Yes, how: ..................  [ ] No
OUTCOME:  [ ] Resolved  [ ] Escalated to: ..................

#6.6 Glossary

TermMeaning
AliasShort internal name of a recipient, distinct from the email address.
AutodiscoverService that automatically hands clients the mailbox configuration.
CASClient Access Services: the client access services, built into the Mailbox role.
CUCumulative Update: a full installation of the product.
DAGDatabase Availability Group: a set of servers hosting replicated copies of the same databases.
DSN / NDRStatus or non-delivery notification generated by the transport system.
EACExchange Admin Center: the web administration console (/ecp).
EMSExchange Management Shell: PowerShell with the Exchange cmdlets.
EWSExchange Web Services: the interface used by many third-party applications.
FailoverUnplanned activation of a database copy on another server.
MAPI over HTTPOutlook's default connection protocol in recent versions.
OABOffline Address Book: the local copy of the address book used by Outlook.
PAMPrimary Active Manager: the DAG node that decides database activations.
SCLSpam Confidence Level: antispam score from 0 to 9.
SESubscription Edition: the subscription edition of Exchange Server.
Shadow redundancyMechanism that keeps a spare copy of messages in transit.
Safety NetStore of already-delivered messages, used to resubmit after a failover.
SwitchoverPlanned move of activity from one server to another.
Edge TransportPerimeter role, in the DMZ, not joined to the domain.

#6.7 Where to look when this guide isn't enough

  • The official Microsoft Learn documentation for Exchange Server is the source of this guide and is updated more often than any internal manual. Search by cmdlet name: the reference page has the full syntax, every parameter and examples.
  • Inside EMS the help is already installed: Get-Help Set-Mailbox -Full and Get-Help Set-Mailbox -Examples answer without leaving the terminal.
  • To find out which permissions a task needs: Get-ManagementRoleAssignment -RoleAssignee <user> shows what an administrator can do.
  • Setup logs live in C:\ExchangeSetupLogs\ExchangeSetup.log. Transport, protocol and connectivity logs live in the logging folders of the Exchange installation.

#A closing note for beginners

Exchange is a platform that forgives little and warns late. The difference between a junior technician who grows quickly and one who accumulates incidents is not how many commands they know by heart: it is the habit of looking before touching, simulating before running, and writing down what they did.

The first few times you will be slow. That is perfectly fine. Speed arrives on its own after a few months; the habit of caution, if you don't build it now, never arrives at all.

No results. Try a cmdlet name (Set-Mailbox), an error code (5.7.1) or a task (quota).

Operational summary of the Microsoft Learn documentation for Exchange Server (Subscription Edition, 2019, 2016). Where they disagree, the official documentation wins: always check before irreversible operations.