> ## Content Index
> Fetch the complete content index at: https://f4n6.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# Using Microsoft Graph and Powershell to Mine for Information - Stale Accounts and Licenses, (Thu, Aug 20th)
- URL: https://f4n6.co.uk/security-feed/using-microsoft-graph-and-powershell-to-mine-for-information-stale-accounts-and-licenses-thu-aug-20th/
- Published: 2026-08-20T21:51:30.000Z
- Updated: 2026-08-20T21:51:30.000Z
- Author: Jeff Davies
- Tags: #security-feed

## 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](https://isc.sans.edu/diary/rss/33264?ref=f4n6.co.uk). 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 →](https://isc.sans.edu/diary/rss/33264?ref=f4n6.co.uk)

*Published via PulseTrace — Adverse Trace threat intelligence.*