Microsoft Entra: come trovare il nome dell’applicazione dall’Application ID (AppId) con Portale, PowerShell e Graph

Hai una lista di Application ID (GUID) di Azure AD / Microsoft Entra e vuoi risalire rapidamente al nome dell’app? In questa guida pratica trovi metodi affidabili, script pronti all’uso e consigli di governance per trasformare ogni GUID in un nome leggibile e gestibile.

Indice

Panoramica del problema

Nel lavoro quotidiano di sicurezza, identity e compliance capita spesso di intercettare Application (client) ID nei log di accesso, in alert SIEM o in report di risk assessment. L’obiettivo è semplice: data una lista di GUID, identificare il corrispondente Application Name (Display Name) per capire chi stia chiedendo accesso e cosa faccia quell’app — così da poter attuare controlli, revoche o eccezioni.

Che cos’è l’Application ID e cosa NON è

  • Application ID (AppId, “client ID”): GUID pubblico che identifica il modello dell’app (oggetto application) e i relativi service principal (oggetti servicePrincipal) nelle directory in cui l’app è presente.
  • Object ID: GUID interno del singolo oggetto nella directory (può essere l’oggetto application o il servicePrincipal). Non è stabile tra tenant diversi e non va confuso con l’AppId.
  • Service Principal (Enterprise application): istanza dell’app nel tuo tenant; è l’oggetto che effettivamente ottiene token e permessi.
  • Managed Identity: speciale service principal usato da risorse Azure; anche qui il appId coincide con il client ID della MI e si risolve nello stesso modo.

Soluzioni operative (a colpo d’occhio)

MetodoQuando usarloVantaggiLimiti / Prerequisiti
Portale Microsoft Entra
Enterprise applications oppure App registrations → ricerca per Application (client) ID
Per applicazioni già presenti nel tuo tenant (service principal o registrazioni di cui sei proprietario)Interfaccia grafica, nessuno script, ottimo per verifiche singole o rapidePer la sola visualizzazione basta Directory Readers / Global Reader; per gestire permessi e revoche serve Cloud Application Administrator (o superiore)
PowerShell (AzureAD o Microsoft Graph)Automazione o verifica di più ID in bloccoScriptabile, esportabile in CSV, funziona anche per oggetti non esposti nel portale (con i permessi giusti)Modulo Microsoft.Graph consigliato; permessi minimi: Application.Read.All (oppure Directory.Read.All)
REST API Microsoft Graph
GET /v1.0/applications?$filter=appId eq '<GUID>'
GET /v1.0/servicePrincipals?$filter=appId eq '<GUID>'
Integrazione con tool esistenti, pipeline CI/CD o piattaforme di securityStandard, veloce, flessibile; puoi ridurre il payload con $select e filtrare con $filterServe un token MS Graph; permessi: Application.Read.All o Directory.Read.All
Catalogo pubblico “Azure App IDs – Security & Compliance”Per app di terze parti che hanno completato la certificazione Microsoft 365Accesso pubblico, utile quando l’app non è (ancora) nel tuo tenantCopr e solo ISV aderenti; non esaustivo per tutte le app multi‑tenant
Escalation su Microsoft Q&A (tag: Azure/Microsoft Entra)Quando l’ID non si trova con gli strumenti precedenti (es. app multi‑tenant non ancora note al tenant)Supporto del team di prodotto o della community specialisticaTempi di risposta variabili; evita di condividere dati sensibili del tenant

Procedura consigliata, passo per passo

  1. Controllo rapido nel portale
    • Apri Entra → Enterprise applications, imposta il filtro su All applications e incolla il GUID nel campo Application ID.
    • Se non trovi nulla, prova in App registrations con lo stesso GUID.
    • Quando trovi un risultato, annota Display name, Verified publisher (se presente) e i permessi assegnati (API permissions e Enterprise applications → Permissions).
  2. Verifica via PowerShell (consigliato se hai decine o centinaia di ID) $ids = @( 'f8d98a96-0999-43f5-8af3-69971c7bb423', '5d661950-3475-41cd-a2c3-d671a3162bc1' ) Microsoft Graph PowerShell (consigliato) Permessi delegati minimi: Application.Read.All (admin consent) Connect-MgGraph -Scopes "Application.Read.All" Select-MgProfile -Name "v1.0" $results = foreach ($id in $ids) { $app = Get-MgApplication -Filter "appId eq '$id'" -ConsistencyLevel eventual -CountVariable c -All $sp = Get-MgServicePrincipal -Filter "appId eq '$id'" -ConsistencyLevel eventual -CountVariable d -All if ($app) { $app | Select-Object @{n='InputAppId';e={$id}}, @{n='Tipo';e={'Application'}}, DisplayName, AppId, Id, PublisherDomain, CreatedDateTime } if ($sp) { $sp | Select-Object @{n='InputAppId';e={$id}}, @{n='Tipo';e={'ServicePrincipal'}}, DisplayName, AppId, Id, AppOwnerOrganizationId, AccountEnabled } } $results | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\AppId-to-Name.csv" Write-Host "Esportato .\AppId-to-Name.csv" Se preferisci il vecchio modulo AzureAD (in deprecazione), i comandi equivalenti sono: Connect-AzureAD Get-AzureADApplication -Filter "AppId eq 'f8d98a96-0999-43f5-8af3-69971c7bb423'" | Select DisplayName, AppId, ObjectId Get-AzureADServicePrincipal -Filter "AppId eq 'f8d98a96-0999-43f5-8af3-69971c7bb423'" | Select DisplayName, AppId, ObjectId
  3. Consulta il catalogo pubblico quando sospetti che l’app sia un ISV noto e non la trovi nel tenant. Il catalogo “Azure App IDs – Security & Compliance” mappa numerosi GUID pubblicati dagli ISV che hanno completato il programma di certificazione Microsoft 365. È utile per riconoscere a colpo d’occhio app comuni (ad es. tool di sicurezza, CRM, HR, backup).
  4. Apri una richiesta su Microsoft Q&A se l’ID continua a comparire nei log ma non è risolvibile con gli strumenti sopra (tipico dei casi multi‑tenant quando il service principal non è stato ancora materializzato nel tuo tenant).

REST: richieste minime e payload ridotto

Qualunque piattaforma in grado di chiamare HTTP può interrogare Microsoft Graph. Ecco le chiamate più utili:

# Cerca una registrazione di applicazione nel tuo tenant (se sei il “publisher”)
GET /v1.0/applications?$filter=appId eq '<GUID>'&$select=displayName,appId,id,publisherDomain,verifiedPublisher

Cerca la enterprise application (service principal) nel tuo tenant

GET /v1.0/servicePrincipals?$filter=appId eq ''&$select=displayName,appId,id,appOwnerOrganizationId,accountEnabled

Esempio con PowerShell “puro” (token già ottenuto):

$token = "<BearerToken>"
$guid  = "f8d98a96-0999-43f5-8af3-69971c7bb423"
$uri   = "https://graph.microsoft.com/v1.0/servicePrincipals`?\$filter=appId eq '$guid'&\$select=displayName,appId,id"

$resp = Invoke-RestMethod -Headers @{Authorization="Bearer $token"} -Uri $uri -Method GET
$resp.value | Format-Table displayName, appId, id

Bulk processing: script completo con gestione errori

Questo script legge GUID da CSV/array, interroga applications e servicePrincipals, restituisce un file unico con la migliore corrispondenza trovata. È pronto per ambienti di audit e SOC.

# Requires: Microsoft.Graph module
csv con colonna AppId (header) oppure usa l'array $ids fallback
$csvPath = ".\input-appids.csv"
$ids = @(
  'f8d98a96-0999-43f5-8af3-69971c7bb423',
  '5d661950-3475-41cd-a2c3-d671a3162bc1'
)

if (Test-Path $csvPath) {
$ids = (Import-Csv $csvPath).AppId | Where-Object { $ -and $.Trim() -ne "" } | Select-Object -Unique
}

Connect-MgGraph -Scopes "Application.Read.All"
Select-MgProfile v1.0

function Resolve-AppId {
param([Parameter(Mandatory)] [string]$AppId)

$AppId = $AppId.Trim().ToLower()
$out = @()

try {
$app = Get-MgApplication -Filter "appId eq '$AppId'" -ConsistencyLevel eventual -All -ErrorAction Stop
if ($app) {
$out += $app | Select-Object @{n='InputAppId';e={$AppId}},
@{n='Tipo';e={'Application'}},
DisplayName, AppId, Id,
PublisherDomain,
@{n='VerifiedPublisher';e={$_.VerifiedPublisher.DisplayName}}
}
} catch { }

try {
$sp = Get-MgServicePrincipal -Filter "appId eq '$AppId'" -ConsistencyLevel eventual -All -ErrorAction Stop
if ($sp) {
$out += $sp | Select-Object @{n='InputAppId';e={$AppId}},
@{n='Tipo';e={'ServicePrincipal'}},
DisplayName, AppId, Id,
AppOwnerOrganizationId,
AccountEnabled
}
} catch { }

if (-not $out) {
[pscustomobject]@{
InputAppId         = $AppId
Tipo               = 'NotFound'
DisplayName        = $null
AppId              = $AppId
Id                 = $null
Info               = 'Nessuna corrispondenza in applications/servicePrincipals'
}
} else {
$out
}
}

$all = foreach ($id in $ids) { Resolve-AppId -AppId $id }
$all | Sort-Object InputAppId, Tipo | Export-Csv -NoTypeInformation -Encoding UTF8 -Path ".\AppId-Resolve-Results.csv"
Write-Host "Esportato: .\AppId-Resolve-Results.csv"

Indagini dai log (Kusto) per contestualizzare

Se hai inviato i log di accesso a Log Analytics o a Microsoft Sentinel, puoi usare KQL per correlare il GUID al display name e capire come e quando viene usata l’app:

// Accessi interattivi utente
SigninLogs
| where AppId == "f8d98a96-0999-43f5-8af3-69971c7bb423"
| summarize accessi=dcount(Id), ultimiAccessi=make_set(TimeGenerated, 5)
          by AppDisplayName, AppId

// Accessi di service principal (app-only / non interattivi)
AADServicePrincipalSignInLogs
| where AppId == "f8d98a96-0999-43f5-8af3-69971c7bb423"
| summarize richieste = count(), ultimi=make_set(TimeGenerated, 5)
by AppDisplayName, AppId, ServicePrincipalId

Queste query aiutano a validare l’associazione GUID‑nome e a stimare l’impatto di un’eventuale revoca.

Pratiche consigliate e trappole comuni

  • Filtra su appId, non su objectId: sono concetti diversi; molti “not found” dipendono da questo errore.
  • Case-insensitive: i GUID non sono case sensitive, ma evita spazi o caratteri extra; applica sempre .Trim().
  • Cerca sia applications che servicePrincipals: la registrazione potrebbe non essere nel tuo tenant, ma il service principal sì (o viceversa).
  • Prima‑party Microsoft: molti servizi Microsoft hanno AppId “ben noti”. È normale trovarli nei log anche senza una tua registrazione locale.
  • App eliminate di recente: verifica anche tra gli elementi eliminati; puoi usare le API /directory/deletedItems/microsoft.graph.application o ...servicePrincipal con lo stesso filtro appId.
  • Migrazione ai moduli Microsoft Graph: i moduli AzureAD/MSOnline sono in deprecazione graduale; standardizza i nuovi script su Microsoft.Graph.
  • Rate limit: in bulk, rispetta i limiti Graph; inserisci un throttle backoff (ad esempio Start-Sleep -Milliseconds 200 ogni 50 richieste).
  • Verifiche di sicurezza: oltre al nome, guarda Verified publisher, App roles / delegated permissions, e i consents attivi.

Permessi e ruoli: il minimo indispensabile

  • Portale Entra: per visualizzare è sufficiente Directory Readers o Global Reader; per modificare/revocare serve Cloud Application Administrator o ruoli superiori.
  • Graph PowerShell / REST:
    • Delegated: Application.Read.All (admin consent) è spesso sufficiente per leggere applications e servicePrincipals.
    • App‑only: usa un’app “tooling” con Application.Read.All o Directory.Read.All, conservando le credenziali in modo sicuro.
  • Principio del minimo privilegio: evita permessi “onnicomprensivi” se non necessari; separa gli strumenti di audit da quelli di gestione.

Governance: evitare futuri “GUID sconosciuti”

  • App consent policy: definisci politiche di consenso utente e “admin consent workflow” per intercettare nuove app prima che diventino operative senza controllo.
  • Review periodica: programma una revisione trimestrale di Enterprise applications, verificando app inattive da >90 giorni, permessi e publisher.
  • Inventario automatizzato: pianifica uno script Graph che esporti quotidianamente DisplayName, AppId, publisher e permessi per riconciliare i log.
  • Tagging e note: usa i campi di descrizione o tag esterni per annotare owner, contatti e finalità dell’app.

Esempi pratici

Singolo GUID dal portale

  1. Apri Enterprise applications e imposta All applications.
  2. Incolla il GUID nel campo Application ID.
  3. Apri la scheda dell’app trovata e verifica Properties → Object ID (per correlare eventuali log) e Permissions.

Singolo GUID da PowerShell (Graph)

Connect-MgGraph -Scopes "Application.Read.All"
Get-MgServicePrincipal -Filter "appId eq '5d661950-3475-41cd-a2c3-d671a3162bc1'" `
  | Select DisplayName, AppId, Id | Format-List

Ridurre il traffico e accelerare

Usa $select per restituire solo i campi necessari e -ConsistencyLevel eventual con -CountVariable quando combini $filter e $search. Esempio REST:

GET /v1.0/servicePrincipals?$filter=appId eq '<GUID>'&$select=displayName,appId,id,appOwnerOrganizationId

Diagnostica: perché non trovo l’app?

  • App non materializzata: per app multi‑tenant, il service principal appare solo al primo consenso. Finché nessuno ha concesso accesso nel tuo tenant, /servicePrincipals non restituisce risultati.
  • L’app non è “tua”: /applications elenca solo le registrazioni del tuo tenant (dove tu sei il publisher). Se l’app è di terze parti, cerca il servicePrincipal.
  • L’app è stata eliminata: controlla i Deleted items via portale o API /directory/deletedItems/....
  • Permessi insufficienti: senza Application.Read.All o Directory.Read.All potresti non vedere nulla via API.
  • Filtro errato: verifica di usare appId eq '<GUID>' e non id/objectId.

Modello di richiesta per Microsoft Q&A

Oggetto: Identificazione AppId <GUID> non risolvibile nel tenant

Dettagli:

- AppId: 
- Dove compare: es. SigninLogs / AADServicePrincipalSignInLogs
- Azioni svolte: ricerche in Enterprise applications e App registrations; query Graph su /applications e /servicePrincipals; controllo Deleted items
- Contesto: multi-tenant? Publisher noto?
- Cosa serve: conferma del nome applicazione e/o publisher

Checklist operativa (rapida)

  • 🔎 Cerca nel portale: Enterprise applications → AppId.
  • 🧰 Esegui lo script Graph (bulk se hai molti GUID).
  • 📊 Correlazione KQL nei log per misurare l’impatto.
  • 📚 Controlla il catalogo pubblico degli App ID pubblicati dagli ISV.
  • ❓ Se ancora ignoto, apri una richiesta su Q&A con tutti i dettagli.
  • 🛡️ Applica governance: consent policy, review periodica e inventario automatizzato.

Domande frequenti

Posso ottenere il nome se l’app non è mai stata usata nel mio tenant?
Sì, se sei il “publisher” (la registrazione è nel tuo tenant) la trovi in /applications. Se è di terze parti e non è mai stata autorizzata, non avrai un servicePrincipal locale; in questo caso prova il catalogo pubblico o l’escalation.

Quale permesso è davvero necessario via Graph?
In lettura, Application.Read.All è sufficiente nella maggior parte dei casi. Directory.Read.All è più ampio e va usato solo se serve.

AzureAD vs Microsoft.Graph?
I moduli AzureAD/MSOnline sono in dismissione; per nuovi script e automazioni usa Microsoft.Graph. I nomi cmdlet cambiano (prefisso Get-Mg*), ma i concetti sono identici.

Esempio completo end‑to‑end

  1. Raccogli i GUID da log (ad es. da alert del SIEM).
  2. Esegui lo script bulk AppId-Resolve e genera CSV.
  3. Unisci il CSV con i log di accesso (join su AppId) per ottenere nome app, frequenza d’uso e utenti coinvolti.
  4. Per le app sconosciute o non verificate, valuta una conditional access che blocchi consensi non governati.
  5. Documenta il risultato aggiungendo note/owner nell’app enterprise e crea un ticket di review.

Template di export (CSV atteso)

InputAppIdTipoDisplayNameAppIdId/ObjectIdPublisher/OrgIdNote
f8d98a96-0999-43f5-8af3-69971c7bb423ServicePrincipalContoso HR Portalf8d98a96-0999-43f5-8af3-69971c7bb4231a2b3c4d-….AppOwnerOrg: 7f8e…Publisher verificato
5d661950-3475-41cd-a2c3-d671a3162bc1ApplicationData Import Engine5d661950-3475-41cd-a2c3-d671a3162bc19e8d7c6b-….PublisherDomain: contoso.comRegistrazione interna
020f8de9-050d-4444-9999-aaaaaaaaaaaaNotFound020f8de9-050d-4444-9999-aaaaaaaaaaaaNon materializzata nel tenant

Riepilogo

Con il portale Entra, Microsoft Graph (PowerShell o REST) e qualche regola di governance puoi associare in modo affidabile ogni Application ID al relativo Application Name. Il flusso ottimale è: ricerca veloce nel portale → risoluzione automatizzata via script → verifica nei log → catalogo pubblico/escation se necessario. Così ottieni un inventario chiaro, riduci i rischi e sei pronto a gestire permessi e revoche con consapevolezza.


Procedura consigliata “tutto in uno” (rapido promemoria)

  1. Portale: cerca il GUID in Enterprise applications; in alternativa in App registrations.
  2. PowerShell (bulk): usa Get-MgServicePrincipal e Get-MgApplication, esporta CSV.
  3. Se serve contesto: interroga i log con KQL (SigninLogs e AADServicePrincipalSignInLogs).
  4. Se non presente nel tenant: controlla il catalogo pubblico degli App ID certificati dagli ISV.
  5. Ancora ignoto? Apri un thread su Q&A con tutti i dettagli tecnici raccolti.
Indice