How to Find Unused Microsoft 365 Copilot Licenses

A short PowerShell script that shows who has a Microsoft 365 Copilot license, who has used it in the last 28 days, and who hasn't.

Written by: Justin

Published on: October 5, 2026

Copilot licenses are easy to hand out and easy to forget. Every few months it is worth asking a simple question: who has a license, and who is actually using it? Microsoft already tracks the answer. This short script pulls that data from Microsoft Graph, prints an adoption number, and saves a list of the people who haven’t used Copilot in the last 28 days so you can follow up with them.

What you need

  • PowerShell 7 and the Microsoft Graph PowerShell SDK. The Microsoft.Graph.Authentication module is all this script uses.
  • The Reports.Read.All permission, and a signed-in account with an admin role that can read usage reports, such as Reports Reader. Microsoft Learn lists the supported roles.
  • One setting to check first. Microsoft hides user names in usage reports by default, so the report may show scrambled IDs instead of real names. To show them, a Global Administrator can clear Conceal user, group, and site names in all reports under Settings > Org Settings > Services > Reports in the Microsoft 365 admin center. That setting applies to the whole tenant, so decide on purpose. Here are the details.

The script

Connect-MgGraph -Scopes 'Reports.Read.All' -NoWelcome

$base = 'https://graph.microsoft.com/v1.0/copilot/reports'
$uri  = "$base/getMicrosoft365CopilotUsageUserDetail(period='D28',version='v2')"
Invoke-MgGraphRequest -Method GET -Uri $uri -OutputFilePath ./CopilotUsage.csv

$report = Import-Csv ./CopilotUsage.csv
if (-not $report) { 'No licensed users in the report.'; return }

$cutoff   = (Get-Date).AddDays(-28)
$inactive = @($report | Where-Object {
    $last = $_.'Last Activity Date'
    -not $last -or [datetime]$last -lt $cutoff
})

$total  = @($report).Count
$active = $total - $inactive.Count
$rate   = $active / $total
'{0} licensed, {1} active in the last 28 days ({2:P0})' -f $total, $active, $rate

$inactive | Export-Csv ./CopilotInactiveUsers.csv -NoTypeInformation
Disconnect-MgGraph | Out-Null

What it does

  • Downloads the 28-day Copilot usage report for every licensed user straight to CopilotUsage.csv.
  • Counts a person as active if their Last Activity Date falls within the last 28 days. The comparison matters. Microsoft says that date is the most recent activity on record, regardless of the report period you pick, so simply checking for a date would also count people who used Copilot months ago.
  • Prints a one-line summary and saves everyone else, both the people with no activity and the people whose last activity is older than 28 days, to CopilotInactiveUsers.csv.

Things to know

  • The report only covers users who have a Microsoft 365 Copilot license. Copilot Chat use by unlicensed people is not counted.
  • Someone showing as inactive is a reason to ask, not a reason to take the license away. They may have been licensed last week, or they may not know what Copilot can do for them yet.
  • The script only reads data. It doesn’t change anything in your tenant.

A fuller version of this script is in my pwsh repository on GitHub. It adds options for the report period, the output folder and device code sign-in, and it warns you when user names are hidden. It is free and open source under the MIT license.

Leave a Comment

Previous

Why Your M365 Architecture is Just a Paper Tiger