đź”§ New: User Management Graph PowerShell Toolkit

Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more — all from one place.

🚀 Launch Toolkit

Fetch Licensed Users & Email Report with Graph PowerShell

Knowing who is licensed in your tenant helps with cost control, access governance, and compliance reporting. This simple script pulls all licensed, enabled member accounts from Microsoft Entra ID (Azure AD) and emails the list (as a CSV attachment) to an administrator using Microsoft Graph PowerShell.


i) Script

# ===== Simple Graph PowerShell Script =====
# Fetch all LICENSED users and email the list to admin
# Requires: Microsoft.Graph module
# Scopes: User.Read.All, Mail.Send

# --- Variables ---
$FromUser  = "admin@contoso.com"     # Sender (must have mailbox)
$To        = "it-ops@contoso.com"    # Recipient
$Subject   = "Licensed users report"
$CsvOutDir = "$env:TEMP"

# --- Connect to Microsoft Graph ---
Import-Module Microsoft.Graph -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All","Mail.Send"

# --- Build Filter: licensed members only, enabled accounts ---
# Note: Using $count in filter requires -ConsistencyLevel eventual (and often -CountVariable)
$filter = "assignedLicenses/`$count ne 0 and userType eq 'Member' and accountEnabled eq true"

# --- Fetch Users ---
$selectProps = "id","displayName","userPrincipalName","jobTitle","department","accountEnabled","createdDateTime"
$users = Get-MgUser -All -Filter $filter -ConsistencyLevel eventual -CountVariable total -Property $selectProps |
Select-Object $selectProps

# --- Export to CSV ---
if (-not (Test-Path -Path $CsvOutDir)) { New-Item -ItemType Directory -Path $CsvOutDir | Out-Null }
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$csvPath = Join-Path $CsvOutDir ("LicensedUsers_{0}.csv" -f $ts)
$users | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

# --- Prepare HTML Body ---
$summaryHtml = @"
<html>
  <body style='font-family:Segoe UI,Arial,sans-serif'>
    <h3>Licensed Users Report</h3>
    <p>Total licensed users: <b>$($users.Count)</b></p>
    <p>The full list is attached as a CSV.</p>
  </body>
</html>
                                
"@
                                
# --- Prepare Attachment ---
$fileBytes     = [System.IO.File]::ReadAllBytes($csvPath)
$base64Content = [System.Convert]::ToBase64String($fileBytes)
$csvFileName   = [System.IO.Path]::GetFileName($csvPath)
$attachment = @{
    "@odata.type" = "#microsoft.graph.fileAttachment"
    name          = $csvFileName
    contentBytes  = $base64Content
    contentType   = "text/csv"
}

# --- Prepare Mail Object ---
$mail = @{
    message = @{
    subject = "${Subject}"
    body    = @{
        contentType = "HTML"
        content     = $summaryHtml
    }
    toRecipients = @(@{ emailAddress = @{ address = $To } })
    attachments  = @($attachment)
    }
    saveToSentItems = $true
}

# --- Send Email ---
Send-MgUserMail -UserId $FromUser -BodyParameter $mail

Write-Host "Done. CSV saved at: $csvPath" -ForegroundColor Green
                                

ii) How the Script Works

  1. Variables
  2. Define the sender/recipient addresses, email subject, and where to save the CSV.

  3. Graph Connection
  4. Loads the unified Microsoft.Graph module and connects with delegated scopes:

    • User.Read.All to read users.
    • Mail.Send to send the email from the $FromUser mailbox.
  5. Filtering Licensed Users
  6. Uses an OData filter that returns only licensed (assignedLicenses/$count ne 0), enabled (accountEnabled eq true) member accounts (userType eq 'Member'). Because $count is referenced in the filter, -ConsistencyLevel eventual (and commonly -CountVariable) is included.

  7. Selecting Properties
  8. Retrieves a concise set of user fields (DisplayName, UPN, JobTitle, Department, etc.) and shapes them with Select-Object.

  9. Exporting the CSV
  10. Creates a timestamped CSV in the specified directory.

  11. Composing and Sending the Email
  12. Builds a brief HTML summary, attaches the CSV as a file attachment, and sends via Send-MgUserMail, saving a copy to Sent Items.


iii) Further Enhancements

  • Add License Names: Post-process assignedLicenses.skuId against Get-MgSubscribedSku to include friendly SKU part numbers.
  • Department/Location Slicing: Add extra filters (e.g., department eq 'Sales') for targeted reports.
  • Scheduling: Run via Task Scheduler or Azure Automation to deliver reports daily/weekly.
  • Inline Preview: Include the first 10 rows as an HTML table in the email body for quick scanning.
  • SharePoint Archival: Upload CSVs to a SharePoint library for versioned audit history.

iv) Use Cases

  • License Compliance: Validate that active employees have the right licenses assigned.
  • Cost Optimization: Identify underused segments by department/region for right-sizing.
  • Onboarding/Offboarding: Confirm license assignment after HR events.
  • Operational Reporting: Provide periodic snapshots to IT leadership and finance.

v) Possible Errors & Solutions

Error Cause Solution
Authorization_RequestDenied Missing delegated consents for User.Read.All or Mail.Send Reconnect with required scopes; admin consent may be needed.
Get-MgUser not recognized Graph module not installed/loaded Install-Module Microsoft.Graph -Scope CurrentUser then Import-Module Microsoft.Graph.
Empty CSV No users match the filter (e.g., all are unlicensed/disabled) Test simpler filters; confirm license assignments in Entra admin center.
Email not delivered $FromUser isn’t mailbox-enabled or lacks permission Use a mailbox-enabled account; verify it can send to $To.
HTML appears plain Client strips styles Keep minimal inline CSS or switch to plain text body.

vi) Conclusion

This lightweight script gives you a reliable, repeatable way to discover licensed users and deliver the results directly to an administrator’s inbox. It’s easy to schedule, simple to extend (e.g., add license names), and perfect for ongoing compliance and cost-control workflows.


Graph PowerShell Explorer Widget

20 Graph PowerShell cmdlets with easily accessible "working" examples.


Permission Required

Example:


                


                


                

© m365corner.com. All Rights Reserved. Design by HTML Codex