Microsoft 365
How to connect to Microsoft 365 from PowerShell, plus admin commands we use regularly.
One-time setup
- Install PowerShell 7. Windows PowerShell 5.1 also works, but 7 is faster and better supported:
winget install --id Microsoft.PowerShell - Open PowerShell 7 and install the two modules for your user account. No admin rights are needed:
Answer Y or A if asked to trust the PSGallery repository.Install-Module ExchangeOnlineManagement -Scope CurrentUser Install-Module Microsoft.Graph -Scope CurrentUser - To update them later:
Update-Module ExchangeOnlineManagement, Microsoft.Graph
Connect to Exchange Online
Connect-ExchangeOnline -UserPrincipalName admin@yourdomain.com
A Microsoft sign-in window opens, and MFA is supported. When you're finished:
Disconnect-ExchangeOnline -Confirm:$false
Export the members of a distribution list
$DGName = "All Staff"
Get-DistributionGroupMember -Identity $DGName -ResultSize Unlimited |
Select-Object Name, PrimarySmtpAddress |
Export-Csv "$env:USERPROFILE\Documents\$DGName.csv" -NoTypeInformation -Encoding UTF8
Change "All Staff" to the list's name. The CSV is saved in your Documents folder under the list's name and opens in Excel.
To export every distribution list to one file:
Get-DistributionGroup -ResultSize Unlimited | ForEach-Object {
$group = $_
Get-DistributionGroupMember -Identity $group.Identity -ResultSize Unlimited |
Select-Object @{n='Group';e={$group.DisplayName}}, Name, PrimarySmtpAddress
} | Export-Csv "$env:USERPROFILE\Documents\All-Distribution-Lists.csv" -NoTypeInformation -Encoding UTF8
Forward a mailbox
Set-Mailbox -Identity jdoe@yourdomain.com -ForwardingSmtpAddress manager@yourdomain.com -DeliverToMailboxAndForward $true
Use -DeliverToMailboxAndForward $false if you don't want a copy kept in the original mailbox. To remove forwarding, set -ForwardingSmtpAddress $null.
Trace a message
Find out whether an email was delivered, blocked or quarantined (covers the last 10 days):
Get-MessageTraceV2 -SenderAddress someone@example.com -StartDate (Get-Date).AddDays(-2) -EndDate (Get-Date) |
Select-Object Received, SenderAddress, RecipientAddress, Subject, Status
Get-MessageTraceV2 replaces the older Get-MessageTrace, which is being retired. Update the module if the command isn't found.
Permanently delete a user account
A deleted user stays in the recycle bin for 30 days. During that time you can't create a new account with the same username. To free it up immediately:
From the admin center
- Go to entra.microsoft.com → Users → Deleted users.
- Select the user and click Delete permanently.
From PowerShell
Connect-MgGraph -Scopes "User.DeleteRestore.All"
# Find the deleted user and copy its Id
Get-MgDirectoryDeletedItemAsUser -All |
Select-Object Id, DisplayName, UserPrincipalName, DeletedDateTime
# Permanently delete it
Remove-MgDirectoryDeletedItem -DirectoryObjectId "<Id from above>"
