A PowerShell module that audits a Microsoft Entra ID tenant for non-human identity risk. Discovers every service principal, app registration, and managed identity; scores each on eight factors; writes an HTML + JSON report your IAM team can act on.
A focused, opinionated audit tool. Four cmdlets: Connect, Get-Inventory, Test-Risk, Export-Report. Runs offline against a 28-record mock tenant for demos; connects to a real tenant via Microsoft.Graph SDK when given a tenant GUID. Same risk-scoring logic both ways. Ships a sample report so you can preview the output without installing anything.
Identity Engineer · NHI Governance Engineer · Cloud Identity (Microsoft) · Security Engineer (IAM)
What the report looks like — exec-summary counts at the top, per-identity cards sorted by risk, each finding paired with a specific remediation. The full HTML is self-contained, drop it on a fileshare or attach it to a ticket.
Each factor produces a finding with a severity, a one-sentence description, and a specific remediation. The factors are deliberately opinionated — the kind of things an IAM lead would call out in a quarterly review.
| Code | Factor | Severity |
|---|---|---|
| NHI001 | No owner assigned | High |
| NHI002 | Created >14 days ago, never signed in | High |
| NHI003 | No sign-in for >90 days (180+ → High; 90–180 → Medium) | High / Med |
| NHI004 | Credential expired but identity still enabled | Critical |
| NHI005 | Credential expires within 30 days | Medium |
| NHI006 | Oldest credential >365 days (rotation policy breach) | Medium |
| NHI007 | Account disabled but credentials still present | Medium |
| NHI008 | Tagged 'legacy' and still enabled | High |
Adding a factor is a function in Test-NhiRisk.ps1. The scoring is linear (per-factor weights add to 0–100) so individual contributions stay readable in a report — no opaque ML model.
PowerShell 7+ on macOS, Linux, or Windows. No Microsoft Graph SDK needed for the mock demo — only for live-tenant mode.
The cmdlets pipe naturally. Get-EntraNhiInventory | Test-NhiRisk | Where-Object RiskLevel -eq 'Critical' gives you just the critical findings; | Export-NhiAuditReport writes the report.
The HTML report is for humans. The JSON output is for everything else.
RiskLevel: Critical — auto-page the on-call IAM engineer with the remediation already attached.Remediation field becomes the ticket description; the owner team gets assigned automatically.