Save time and simplify Microsoft 365 management with PowerShell

Table of contents
PowerShell offers IT admins a faster way to manage Microsoft 365 at scale. Learn how to connect to your tenant through the Microsoft Graph PowerShell SDK and other service modules to automate routine tasks—and explore five essential commands every IT admin should know.
Managing Microsoft 365 (formerly Office 365) can get complicated fast. Between user accounts, licenses, mailboxes, Teams policies, and SharePoint sites, everyday administration often means jumping between several admin centers to get things done. It works, but it’s not exactly efficient, especially as your organization grows.
PowerShell helps streamline that work. By letting you interact directly with Microsoft 365 services, it gives you a faster, more scalable way to manage your environment. With just a few cmdlets, you can perform bulk updates, run quick reports, and automate day-to-day maintenance tasks—all from one centralized scripting environment that complements purpose-built Microsoft 365 management tools.
In this guide, we’ll cover everything you need to get started. You’ll learn how PowerShell connects with Microsoft 365’s suite of online services, which modules to use, and five of the most useful PowerShell commands for daily administration to keep your tenant secure, productive, and easy to maintain.
Microsoft 365 and PowerShell: What to know before you begin the connection
Before installing the necessary modules and running commands, it helps to understand how PowerShell interacts with Microsoft 365.
PowerShell connects to your tenant through modules—collections of cmdlets that let you interact with Microsoft 365 online services such as Exchange Online, SharePoint Online, and Microsoft Teams. Each module communicates with Microsoft’s APIs to read or modify settings, enabling you to automate routine administration across your environment.
The Microsoft Graph PowerShell SDK is the most important of these. It provides a single, modern interface to Microsoft Entra ID (formerly Azure Active Directory, or Azure AD) and an expanding range of Microsoft 365 services, letting you manage users, groups, licenses, and reports from one unified tool. It replaces the older Microsoft Azure AD and Microsoft Online (MSOnline) PowerShell modules.
That said, many workloads still have their own dedicated modules, which remain necessary for certain service-specific admin tasks. Graph is steadily gaining coverage across Microsoft Exchange, SharePoint Online, and Teams, but it doesn’t yet replace every cmdlet in those individual modules.
You can install and use these modules side by side, loading only the ones you need. Many admins connect to multiple services, such as the Microsoft Graph and Exchange Online modules, in the same session to handle cross-service automation tasks from a single PowerShell window. Just make sure you’re using the latest module versions to avoid authentication conflicts. See Microsoft’s official documentation to learn more about how to use a single instance of PowerShell to manage Microsoft 365 accounts
Prerequisites before connecting
To run PowerShell with Microsoft 365, make sure your system meets these requirements:
- PowerShell 7.2 or later recommended (though modules remain compatible with Windows PowerShell 5.1)
- .NET Framework 4.7.2 or later if using Windows PowerShell 5.1
- Latest PowerShellGet module installed (update to the latest version using
Install-Module PowerShellGet) - The PowerShell script execution policy must be set to
remote signedorless restrictive. Use Get-ExecutionPolicy to determine the current execution policy if unsure. For more information about execution policies, see Microsoft’s official documentation.
You’ll also need to have Microsoft 365 admin credentials with the appropriate permissions to manage the services you want to connect to.
Operating-system compatibility
PowerShell 7 works on Windows, macOS, and Linux. Windows admins typically prefer the native Windows PowerShell for compatibility with on-premises Active Directory and credential stores, while PowerShell 7+ offers better cross-platform support.
Tip: Microsoft has officially deprecated older modules like Azure AD and MSOnline. If you’ve been using Azure AD PowerShell, follow Microsoft’s official Graph migration guide. The syntax is different, but the functionality is broader and more secure. If you’re still using Microsoft Online (MSOnline), you should also update your PowerShell commands to use the Microsoft Graph PowerShell SDK cmdlets instead. You can use the MSOnline-to-Graph mapping table as a reference..
How to connect to Microsoft 365 with PowerShell
Before you can run commands, you’ll need to install the right PowerShell modules and then connect to your Microsoft 365 tenant. The process typically involves two steps: installing the modules and authenticating your session.
Step 1: Install the required PowerShell modules
Open PowerShell as an administrator and install the Microsoft Graph PowerShell SDK first. This module provides core access to Microsoft Entra ID and other tenant-wide resources.
To install the v1 module of the SDK in PowerShell 7+ or Windows PowerShell 5.1, run the following command:
Install-Module Microsoft.Graph
To install the beta module, run the following command:
Install-Module Microsoft.Graph.Beta
Important: Use Microsoft Graph v1.0 for any production scripts. The beta endpoint is intended for testing or early adoption only and can change without notice. Also note that installing the SDK in one version of PowerShell runtime doesn’t install it in the other. Run the version of PowerShell you intend to use it in. See Microsoft’s official Graph PowerShell SDK installation guidance for more details.
If you plan to manage additional workloads, install their corresponding modules as well, substituting the appropriate module name.
Step 2: Connect to your Microsoft 365 tenant
Once your modules are installed, you can connect PowerShell to Microsoft 365 and start managing your environment. Here’s how:
Connect using Microsoft Graph PowerShell module
1. Open PowerShell.
2. Import the Microsoft Graph module into your session by running this command:
Import-Module Microsoft.Graph
3. Then, you’ll need to authenticate with your Microsoft 365 admin account by running the Connect-MgGraph cmdlet (which replaces Connect-MsolService and Connect-Azure AD in the deprecated MSOnline and Azure Active Directory PowerShell modules) to sign in with the required scopes:
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
The command prompts you to sign in with your admin credentials. Once authenticated, you’ll see a “Welcome to Microsoft Graph!” message. You only need to sign in once per PowerShell session (until you close the window or run Disconnect-MgGraph).
Note: Each Microsoft Graph API requires specific permission scopes. The example above requests broad scopes that cover most user, group, and policy management tasks, but Microsoft recommends requesting only the scopes your script needs as a security best practice. You can use Find-MgGraphCommand to discover which scopes other cmdlets require, or check out Microsoft’s official documentation for an overview of Microsoft Graph permissions.
Connect to other Microsoft 365 service modules
You can connect to these services individually by following the first two steps outlined above, substituting the appropriate module name in Step 2. For Step 3, enter one of the following commands (replacing the sample URL for the SharePoint Online PowerShell module with your own):
# Connect to Exchange Online
Connect-ExchangeOnline
#Connect to SharePoint Online
Connect-SPOService -Url https://contoso-admin.sharepoint.com
#Connect to Microsoft Teams
Connect-MicrosoftTeams
Automation tip: These connection commands (including for Microsoft Graph) use modern authentication (OAuth 2.0) and support MFA. However, interactive sign-in isn’t suitable for unattended automation. For scheduled scripts or background jobs, use certificate-based or managed identity authentication. See Microsoft’s app-only authentication guidance for Exchange Online, Teams, and Graph PowerShell. Some SharePoint Online management tasks not yet supported in Graph may still be automated with PnP.PowerShell, a modern, community-maintained module that lets you create an app-only registration for secure, unattended access.
5 essential PowerShell scripts for Microsoft 365 admins
Once you’ve connected, these PowerShell commands can save hours of clickwork. Here are five practical, high-impact ones you can drop into your toolkit.
1. Get a list of all Microsoft 365 users in your tenant
Need a clean CSV of every account for audits or quick lookups? Get-MgUser in the Microsoft Graph PowerShell module pulls user objects from Microsoft Entra ID (formerly Azure Active Directory) so you can export exactly the fields you care about.
Connect to the Graph PowerShell SDK using the Connect-MgGraph command (formerly Connect-MsolService and Connect-Azure AD in MSOnline and Azure AD modules). Then run the following command, making sure you replace the file path (C:\Temp\AllUsers.csv) with your preferred save location and file name:
# Connect to Microsoft Graph (requires User.Read.All)
Connect-MgGraph -Scopes "User.Read.All"
# Export all users to CSV
Get-MgUser -All |
Select DisplayName, Id, Mail, CreatedDateTime |
Export-Csv "C:\Temp\AllUsers.csv"
The resulting CSV file includes each account’s display name, ID, primary email address (the one associated with the user’s mailbox, if applicable), and creation date—giving you a snapshot of all the Microsoft 365 users in your tenant.
Note: The Get-MgUser cmdlet in the Microsoft Graph PowerShell SDK replaces the Get-AzureADUser and Get-MsolUser cmdlets from the Azure AD and MSOnline PowerShell modules, now deprecated.
You can also adapt this same approach with other Microsoft Graph cmdlets to export different types of directory data. For example:
Get-MgGroup: Lists all Microsoft 365 groupsGet-MgGroupMember-GroupId <GroupId>: Lists members of a specific groupGet-MgGroupOwner-GroupId <GroupId>: Lists group ownersGet-MgTeam: Retrieves Microsoft Teams informationGet-MgDevice: Lists registered devices
Each of these commands retrieves information about a different type of object in Microsoft Entra ID—such as groups, group members, and devices—or a connected Microsoft 365 resource, in the case of teams. You can alter the properties listed after Select to specify which details (that is, object properties) to include, or add a Filter or Search parameter (where supported) to narrow down the output before exporting.
For example, you can run the following PowerShell command if you want only project-based groups (i.e., those with “Project” in the title):
# Connect to Microsoft Graph (requires Group.Read.All)
Connect-MgGraph -Scopes "Group.Read.All"
# Export all Microsoft 365 groups with "Project" in the name
Get-MgGroup -Filter "startswith(DisplayName,'Project')" |
Select DisplayName, Id, Description, Mail, Visibility |
Export-Csv "C:\Temp\ProjectGroups.csv"
2. Find users without multifactor authentication (MFA) enabled
Want a quick list of who still hasn’t registered any multi-factor authentication (MFA) methods? MFA registration details are stored in Microsoft Entra ID and can be retrieved using the Get-MgUserAuthenticationMethod cmdlet from the Graph SDK.
Run the following command to generate a list of all users who do not have any MFA method—such as the Microsoft Authenticator app, FIDO2 key, or phone-based verification—registered, and export the results to a CSV file:
# Connect to Microsoft Graph (requires UserAuthenticationMethod.Read.All)
Connect-MgGraph -Scopes "UserAuthenticationMethod.Read.All"
# Get all users in the tenant
$users = Get-MgUser -All
# Check each user for registered MFA methods
$noMfaUsers = foreach ($user in $users) {
$methods = Get-MgUserAuthenticationMethod -UserId $user.Id
if (-not $methods) {
[PSCustomObject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
MFARegistered = $false
}
}
}
# Export list of users without MFA
$noMfaUsers | Export-Csv "C:\Temp\UsersWithoutMFA.csv"
This produces a clear list to chase—perfect for nudges or an automated reminder flow..
3. Assign or remove Microsoft 365 licenses
Your organization recently upgraded from Office 365 E3 to Microsoft 365 E5, but a few accounts slipped through the cracks. Instead of clicking through the admin center to track them down, you can use PowerShell to quickly find every user still assigned an E3 license—and export the results to a CSV file for review or cleanup.
This quick Microsoft Graph PowerShell command combines the Get-MgSubscribedSku and Get-MgUser cmdlets (formerly Get-MsolUser in MSOnline/Get-MsolUser in Azure AD modules) with a few built-in PowerShell commands to filter and export your results:
# Connect to Microsoft Graph (requires User.ReadWrite.All and Organization.Read.All)
Connect-MgGraph -Scopes "User.ReadWrite.All","Organization.Read.All"
# Identify the Office 365 E3 SKU
$e3Sku = Get-MgSubscribedSku -All | Where-Object SkuPartNumber -eq 'ENTERPRISEPACK'
# Find all users assigned the E3 license and export to CSV
Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($e3Sku.SkuId))" -ConsistencyLevel eventual -All |
Select-Object Id |
Export-Csv ".\O365E3_Users.csv"
Now that you’ve exported all users still holding an O365 E3 license, you can use that CSV to assign them Microsoft 365 E5 licenses in one go.
# Identify the Microsoft 365 E5 SKU
$e5Sku = Get-MgSubscribedSku -All | Where-Object SkuPartNumber -eq 'SPE_E5'
# Assign Microsoft 365 E5 licenses to all previously exported users
Import-Csv ".\O365E3_Users.csv" | ForEach-Object {
Set-MgUserLicense -UserId $_.Id -AddLicenses @{SkuId = $e5Sku.SkuId}
}
Once you’ve verified that all the new licenses have been correctly added to your list of users, you can go ahead and remove the old O365 E3 licenses to complete the transition using the same CSV:
# Remove Office 365 E3 licenses from all previously exported users
Import-Csv ".\O365E3_Users.csv" | ForEach-Object {
Set-MgUserLicense -UserId $_.Id -RemoveLicenses @{SkuId = $e3Sku.SkuId}
}
That’s your tidy cut-over: assign the new license, confirm, then retire the old one.
4. Audit or tighten tenant-wide SharePoint sharing defaults
Before you make changes, take a snapshot of your current SharePoint Online/OneDrive for Business tenant settings. Then, if your policy calls for a “tighter” baseline, you can restrict external sharing and reshares in one go.
Tenant sharing lives in your SharePoint Online admin settings (backed by Microsoft Entra ID) and is exposed in Graph via the SharePoint admin settings resource. You can audit what’s configured now, back it up, and (if needed) tighten defaults with two cmdlets:
Get-MgAdminSharepointSetting: Read the current tenant settingsUpdate-MgAdminSharepointSetting: Change one or more settings
A) Audit & back up current settings
# Read-only connect (audit)
Connect-MgGraph -Scopes "Sites.Read.All"
# Inspect everything
Get-MgAdminSharepointSetting | Format-List *
# Optional: save a snapshot (handy before any change)
(Get-MgAdminSharepointSetting | ConvertTo-Json -Depth 5) | Set-Content ".\SharePointSettings_Backup.json"
Tip: To see the exact property names you can set, run:
Get-MgAdminSharepointSetting | Get-Member -MemberType NoteProperty
B) Tighten sharing defaults (common baseline)
The example below does three things that most orgs consider a “tight” default posture:
- Limit external sharing to existing guests only
- Make the default sharing link type View (not Edit)
- Scope the default sharing link to organization (not “anyone”)
# Write connect (update)
Connect-MgGraph -Scopes "Sites.ReadWrite.All"
# Tighten tenant-wide defaults (adjust to your policy)
Update-MgAdminSharepointSetting `
-SharingCapability ExistingExternalUserSharingOnly `
-DefaultSharingLinkType View `
-DefaultSharingLinkScope Organization
# Quick verify
Get-MgAdminSharepointSetting | Select SharingCapability, DefaultSharingLinkType, DefaultSharingLinkScope
For a deeper dive into reporting, check out how to build the perfect SharePoint permissions report.
5. Audit inactive Microsoft 365 accounts
Stale accounts cause license creep and are one of the most common cleanup and security pain points for IT admins. Using Microsoft Graph’s Get-MgUser cmdlet, you can pull each user’s last sign-in (when available) and flag anyone inactive over a set threshold (e.g., 90 days)—helping you reclaim licenses or disable stale accounts before they become security risks.
# Connect to Microsoft Graph (requires AuditLog.Read.All and User.Read.All)
Connect-MgGraph -Scopes "AuditLog.Read.All","User.Read.All"
# Get all sign-in logs from the past 90 days and join to user list
$cutoff = (Get-Date).AddDays(-90)
# Retrieve users who haven't signed in recently
$inactiveUsers = Get-MgUser -All -Property "Id,DisplayName,UserPrincipalName,SignInActivity" |
Where-Object {
-not $_.SignInActivity.LastSignInDateTime -or
([datetime]$_.SignInActivity.LastSignInDateTime -lt $cutoff)
}
# Export to CSV for review or deprovisioning
$inactiveUsers |
Select DisplayName, Id, UserPrincipalName, @{n='LastSignIn';e={$_.SignInActivity.LastSignInDateTime}} |
Export-Csv ".\InactiveUsers_90Days.csv"
You’ll get an actionable CSV of “clean-up candidates” to review, disable, or reclaim licenses.
READ ALSO: Explore more PowerShell script examples to automate Microsoft 365 administration tasks that go beyond what’s covered here. Or see how to simplify Microsoft 365 migration projects with ShareGate’s PowerShell module.
PowerShell gives Microsoft 365 admins a faster, more flexible way to manage their environment—especially when you’re dealing with hundreds of users, sites, or licenses. Once you know how to connect to your tenant and run a few key cmdlets, you can turn routine admin work into repeatable, automated processes that save serious time.
That said, scripting isn’t for everyone—or for every scenario. Even seasoned admins know that one misplaced parameter can have ripple effects across your tenant.
That’s where ShareGate can help. It brings the same control and automation benefits of PowerShell into an intuitive, visual interface. From permissions cleanup to SharePoint migrations, you can manage, monitor, and report on your Microsoft 365 environment—without writing or debugging scripts.
Explore how ShareGate makes Microsoft 365 management simpler →


.avif)
%20(1).avif)
.png)












.png)