How to use Azure CLI to Generate Documentation for Azure AD Applications?
Your organization likely has hundreds of Azure AD Applications. And with the constant addition, development and subset of new applications with various access points, it becomes imperative to use a script that streamlines the documentation process and helps creates technical documentation for every registered application. And that’s where the following script steps in.
What is Azure Active Directory?
Azure Active Directory is an Identity and Access Management (IAM) system. It provides a single place to store information about digital identities. You can configure your applications to use Azure AD as the place where user information is stored.
Advantages of generating documentation for Azure AD Applications
- Improves the experience for developers using your Azure AD Applications
- Decreases the amount of time spent on-boarding developers and application integration partners.
- Leads to good maintenance and quicker updates.
- API permissions, scopes, roles help developers and integration partners to understand the Azure AD Application and know what it can do
- Decreases the amount of time spent on decoding unexpected errors when using it.
In this article, I have attached a PowerShell script that takes the details of the given Azure AD Applications as input and creates readable markdown documentation that you can share with developers and integration partners using the simple use of Azure’s CLI commands.
Prerequisites
- Azure CLI
- Azure AD Applications registered in Azure tenant
- Azure Application Administrator / Developer role
- Login to Azure using Azure CLI before executing following script
Note - This code has not been optimized and is for demo purpose. You might need to modify the code as per your requirements.
PowerShell Script
function GetTenantId() {
$accountDetails = az account list | ConvertFrom-Json
return $accountDetails.tenantId
}
function GetAadApplications() {
return (az ad app list --all) | ConvertFrom-Json
}
function GenerateDocumentation($aadApplications) {
$progressCountApp = 1;
ForEach ($appInfo in $aadApplications) {
Write-Progress -Id 0 -Activity "Generating Documentation for the App: $($appInfo.displayName)" -Status "App $progressCountApp of $($aadApplications.length)" -PercentComplete (($progressCountApp / $aadApplications.length) * 100)
$outputDocumentPath = -join ($outputFolderPath, "\" , $appInfo.displayName, ".md")
$fragments = @()
$fragments += "# $($docTitle)`n"
$fragments += "$($docDescription)`n"
$fragments += "## App Details"
$fragments += "| Property | Value |"
$fragments += "| ------ | ------ |"
$fragments += "|Display Name|$($appInfo.displayName)|"
$fragments += "|App Id|$($appInfo.appId)|"
$fragments += "|Publisher Domain|$($appInfo.publisherDomain)|"
$fragments += "`n## Resource Access"
ForEach ($resource in $appInfo.requiredResourceAccess) {
$currentResource = (az ad sp show --id $resource.resourceAppId) | ConvertFrom-Json
$resourceName = $currentResource.displayName
if (![string]::IsNullOrEmpty($resourceName)) {
$fragments += "`n### $($resourceName)"
}
if ($resource.resourceAccess) {
$fragments += "`n_App Roles_"
$fragments += "| Role |"
$fragments += "| ------ |"
$appRoles = (az ad sp show --id $resource.resourceAppId --query "appRoles[].{Value:value, Id:id}") | ConvertFrom-Json
ForEach ($access in $resource.resourceAccess) {
$appRole = ($appRoles | Where-Object { $_.Id -eq $access.id })
$appRoleName = $appRole.Value
if (![string]::IsNullOrEmpty($appRoleName)) {
if (![string]::IsNullOrEmpty($appRoleName)) {
$fragments += "|$($appRoleName)|"
}
}
}
}
if ($resource.oauth2Permissions) {
$fragments += "`n_OAuth2 Permissions_"
$fragments += "| Permission |"
$fragments += "| ------ |"
$oauth2Permissions = (az ad sp show --id $resource.resourceAppId --query "oauth2Permissions[].{Value:value, Id:id}") | ConvertFrom-Json
ForEach ($oauth2Permission in $resource.oauth2Permissions) {
$appOauth2Permission = ($oauth2Permissions | Where-Object { $_.Id -eq $oauth2Permission.id })
$appOauth2PermissionName = $appOauth2Permission.Value
if (![string]::IsNullOrEmpty($appOauth2PermissionName)) {
$fragments += "|$($appOauth2PermissionName)|"
}
}
}
}
$fragments += "`n_report run $(Get-Date)_"
$fragments | out-file -FilePath $outputDocumentPath
$progressCountApp++
}
Write-Progress -Id 0 -Activity " " -Status " " -Completed
}
$docTitle = "Azure AD Application Details"
$docDescription = "This is a script generated documentation. For more details contact teamname_GDL@yourcompany.com"
$outputFolderPath = $PSScriptRoot
$aadApplications = GetAadApplications
GenerateDocumentation $aadApplications
Output

I would like to thank Jayakumar Balasubramaniam for the support he provided to review and finalize this script.
Published on:
Learn moreRelated posts
Azure Developer CLI (azd): Run and test AI agents locally with azd
New azd ai agent run and invoke commands let you start and test AI agents from your terminal—locally or in the cloud. The post Azure Developer...
Microsoft Purview compliance portal: Endpoint DLP classification support for Azure RMS–protected Office documents
Microsoft Purview Endpoint DLP will soon classify Azure RMS–protected Office documents, enabling consistent DLP policy enforcement on encrypte...
Introducing the Azure Cosmos DB Plugin for Cursor
We’re excited to announce the Cursor plugin for Azure Cosmos DB bringing AI-powered database expertise, best practices guidance, and liv...
Azure DevOps Remote MCP Server (public preview)
When we released the local Azure DevOps MCP Server, it gave customers a way to connect Azure DevOps data with tools like Visual Studio and Vis...
Azure Cosmos DB at FOSSASIA Summit 2026: Sessions, Conversations, and Community
The FOSSASIA Summit 2026 was an incredible gathering of developers, open-source contributors, startups, and technology enthusiasts from across...
Dataverse: Avoid Concurrency issues by using Azure Service Bus Queue and Azure Functions
Another blog post to handle the concurrency issue. Previously, I shared how to do concurrency via a plugin in this blog post and also how to f...
March Patches for Azure DevOps Server
We are releasing patches for our self‑hosted product, Azure DevOps Server. We strongly recommend that all customers stay on the latest, most s...
Azure Developer CLI (azd): Debug hosted AI agents from your terminal
New azd ai agent show and monitor commands help you diagnose hosted AI agent failures directly from the CLI. The post Azure Developer CLI (azd...
A Look Ahead at Azure Cosmos DB Conf 2026: From AI Agents to Global Scale
Join us for Azure Cosmos DB Conf 2026, a free global, virtual developer event focused on building modern applications with Azure Cosmos DB. Da...