~/f4n6 $ grep -r "Using Microsoft Graph and Powershell to Mine for Information - Stale Accounts and Licenses, (Thu, Aug 20th)" ./investigations/ --include="*.md"

Using Microsoft Graph and Powershell to Mine for Information - Stale Accounts and Licenses, (Thu, Aug 20th)

Jeff Davies 20 Aug 2026 4 min read

1. Executive summary

SANS Internet Storm Center published a Microsoft Graph PowerShell workflow for identifying enabled Entra accounts, sign-in history, password-change dates and assigned Microsoft 365 licences. This is a defensive administrative guide; it does not report a breach, threat campaign, vulnerability, malicious actor or active exploitation. EMEA financial institutions can use the workflow to identify potentially stale accounts and unnecessary licences, but must validate business ownership and usage before disabling or deleting anything. No CVE, CVSS severity or CISA KEV exploitation state applies to this item.

2. Regulatory framing

No specific DORA/NIS2 article is directly engaged by this item.

3. Technical analysis & attack chain

Confirmed attack chain: None. The source describes an authorised tenant-audit workflow, not malicious activity.

Source-confirmed administrative workflow

  1. Prepare the Microsoft Graph PowerShell module. The source provides the following installation and import commands:

powershell Install-Module Microsoft.Graph -Repository PSGallery Install-Module Microsoft.Graph.Beta -Repository PSGallery Import-Module Microsoft.Graph

Microsoft.Graph.Beta is described as optional. The article refers to version 2.3.9, but does not establish whether this identifies the API, PowerShell SDK/module or another component; it should not be treated as a deployment requirement.

  1. Connect to the Entra tenant. The supplied extract renders the connection command as:

powershell Connect-MgGraph -Scopes "User.Read.All

The line is incomplete as supplied because the quotation mark is not closed. Validate the syntax and requested scope through the institution’s normal change process before execution.

  1. Enumerate all enabled users. The following pipeline requests identity and sign-in properties and filters for enabled accounts:

powershell $AllUsers = Get-MgUser -All -Property Id, DisplayName, UserPrincipalName, AccountEnabled, SignInActivity | Where-Object { $_.AccountEnabled -eq $true }

The source states that Microsoft Graph returns only the first 100 objects by default in this context. Omitting -All can therefore produce an incomplete tenant inventory.

  1. Retrieve password-change information. LastPasswordChangeDateTime is not included in the source’s described default result set and must be requested explicitly:

powershell Get-MgUser -All -Property DisplayName, UserPrincipalName, LastPasswordChangeDateTime | Select-Object DisplayName, UserPrincipalName, LastPasswordChangeDateTime

  1. Resolve licence assignments. Querying AssignedLicenses returns SkuId GUIDs:

powershell Get-MgUser -UserId $u -Property AssignedLicenses | Select-Object -ExpandProperty AssignedLicenses

The source uses Get-MgUserLicenseDetail to obtain human-readable SKU part numbers:

powershell Get-MgUserLicenseDetail -UserId $u | Select-Object SkuId, SkuPartNumber

The supplied examples map as follows:

SkuId SkuPartNumber
05e9a617-0261-4cee-bb44-138d3ef5d965 SPE_E3
639dec6b-bb19-468b-871c-c5c441c4b0cb Microsoft_365_Copilot
5b631642-bd26-49fe-bd20-1daaa972ef80 POWERAPPS_DEV
a403ebcc-fae0-4ca2-8c8c-7a907fd6c235 POWER_BI_STANDARD
f30db892-07e9-47e9-837c-80727f46fd3d FLOW_FREE
  1. Build the review dataset. The source requests these properties:

powershell $Properties = @( 'AccountEnabled', 'City', 'Country', 'Department', 'DisplayName', 'JobTitle', 'UserPrincipalName', 'CreatedDateTime', 'SignInActivity', 'LastPasswordChangeDateTime' )

It derives interactive sign-in, non-interactive sign-in and licence fields with:

powershell @{N='LastInteractiveSignInDate';E={$_.SignInActivity.LastSignInDateTime}} @{N='LastNonInteractiveSignInDate';E={$_.SignInActivity.LastNonInteractiveSignInDateTime}} @{N='License';E={(Get-MgUserLicenseDetail -UserId $_.UserPrincipalName).SkuPartNumber -join '; '}}

The source warns that sign-in lookups add processing time and that Get-MgUserLicenseDetail executes separately for each user.

  1. Review and export. The resulting dataset can be reviewed through Out-GridView or exported for spreadsheet analysis. The article refers to Out-CSV but supplies neither a destination nor a complete export command; validate the export method before operational use.

No initial-access vector, exploited component, CVE, payload, persistence, privilege escalation, command-and-control, lateral movement, exfiltration or malicious impact is reported. No threat actor is named and no attribution is made.

Both supplied records resolve to the same SANS ISC article. The technical claims are therefore single-sourced; verify before enforcement.

4. Mitigation & containment

P1 — within 24 hours

  • Run a controlled, read-only inventory of enabled Entra accounts using Get-MgUser -All; confirm that -All is present so the review is not limited to the first 100 objects.
  • Collect AccountEnabled, UserPrincipalName, CreatedDateTime, SignInActivity and LastPasswordChangeDateTime.
  • Validate the incomplete Connect-MgGraph command and requested User.Read.All scope before execution.
  • Immediately disable only accounts independently confirmed as stale and no longer required. Do not delete accounts solely because a sign-in timestamp is old or absent.
  • Protect exported results as sensitive identity data: the proposed dataset includes user principal names, locations, departments and job titles.

P2 — within 72 hours

  • Resolve licence GUIDs with Get-MgUserLicenseDetail -UserId and review the returned SkuPartNumber values.
  • Compare interactive and non-interactive sign-in dates before classifying an account as inactive.
  • Confirm account ownership and business need before disabling an identity or reclaiming its licences.
  • Reclaim licences only after confirming they are unused. Defer account deletion until dependency and retention checks are complete.
  • Account for the per-user licence-detail calls when scheduling the query against large tenants.

P3 — within seven days

  • Establish a recurring stale-account and licence review using the same explicit property set.
  • Record the owner, evidence reviewed, disposition and approval for every disablement, deletion or licence removal.
  • Review the output in Out-GridView or an approved export workflow; do not operationalise the source’s incomplete Out-CSV reference without validation.
  • Reconcile the recurring report with the institution’s existing identity lifecycle process.

There is no vendor patch, fixed version, registry change, firewall block or malware-containment action associated with this item.

5. Indicators of compromise

No indicators of compromise available in the source material. The source contains legitimate administrative commands, not confirmed malicious observables.

Behavioural indicators

behaviour where to observe confidence
Bulk Get-MgUser -All queries requesting SignInActivity and LastPasswordChangeDateTime PowerShell execution telemetry on the administrative endpoint High that the workflow is source-described; no compromise specificity
Repeated Get-MgUserLicenseDetail -UserId calls across tenant users PowerShell execution telemetry and Microsoft Graph activity records, if collected High that the workflow is source-described; no compromise specificity
Results passed to Out-GridView or the source-described Out-CSV workflow PowerShell and filesystem telemetry on the administrative endpoint High that the workflow is source-described; no compromise specificity

These behaviours are single-sourced; verify before enforcement and do not treat them as proof of compromise.

6. Detection

Insufficient indicators to author detection rules.

7. Sources

  • SANS Internet Storm Center, Rob VandenBrink, “Using Microsoft Graph and Powershell to Mine for Information - Stale Accounts and Licenses,” 20 August 2026: https://isc.sans.edu/diary/rss/33264

8. Adverse Trace position

Adverse Trace assesses this as an informational identity-governance advisory, not a vulnerability or active-threat alert. No CVE, CVSS severity, CISA KEV state, confirmed compromise or actor attribution applies. The workflow can support stale-account reduction and licence recovery, but its commands and operational assumptions are single-sourced; verify before enforcement, particularly the truncated connection command and incomplete export reference. Adverse Trace will monitor for the source’s indicated follow-on security material and update clients if threat-specific behaviours or indicators emerge.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies