Get-AzEnterpriseAppConfig.ps1


Description

Purpose

Retrieves configuration details for an enterprise application (service principal) using the Microsoft.Entra module.

Detailed Description

Resolves a service principal by application ID or object ID, fetches the backing application, and gathers related configuration such as redirect URIs, required resource access, owners, credentials, and assigned permissions. The function imports Microsoft.Entra, ensures the necessary scopes are granted, and returns a consolidated object containing both application and service principal properties.

Back to Top

Usage

Example 1

PS C:\> Get-AzEnterpriseAppConfig -AppIdOrObjectId '00000000-0000-0000-0000-000000000000'

Retrieves the enterprise application details for the specified application ID.

Example 2

PS C:\> '00000000-0000-0000-0000-000000000000' | Get-AzEnterpriseAppConfig -Verbose

Uses pipeline input and emits verbose output while collecting the configuration information.

Back to Top

Notes

Requires Microsoft.Entra PowerShell module 1.0.10 or later, Microsoft.Graph.Authentication module, and permissions granting the following scopes: Application.Read.All, Directory.Read.All, AppRoleAssignment.Read.All, DelegatedPermissionGrant.Read.All.

Back to Top


Script

function Get-AzEnterpriseAppConfig {
    <#
    .SYNOPSIS
    Retrieves configuration details for an enterprise application (service principal) using the Microsoft.Entra module.

    .DESCRIPTION
    Resolves a service principal by application ID or object ID, fetches the backing application, and gathers
    related configuration such as redirect URIs, required resource access, owners, credentials, and assigned
    permissions. The function imports Microsoft.Entra, ensures the necessary scopes are granted, and returns a
    consolidated object containing both application and service principal properties.

    .PARAMETER AppIdOrObjectId
    The application (client) ID or the object ID of the enterprise application (service principal) to retrieve.
    Accepts pipeline input.

    .PARAMETER SkipConnect
    Skips calling Connect-Entra when set. Use this if a Microsoft.Entra connection with the required scopes
    already exists.

    .EXAMPLE
    PS C:\> Get-AzEnterpriseAppConfig -AppIdOrObjectId '00000000-0000-0000-0000-000000000000'

    Retrieves the enterprise application details for the specified application ID.

    .EXAMPLE
    PS C:\> '00000000-0000-0000-0000-000000000000' | Get-AzEnterpriseAppConfig -Verbose

    Uses pipeline input and emits verbose output while collecting the configuration information.

    .NOTES
    Requires Microsoft.Entra PowerShell module 1.0.10 or later, Microsoft.Graph.Authentication module, and permissions
    granting the following scopes: Application.Read.All, Directory.Read.All, AppRoleAssignment.Read.All,
    DelegatedPermissionGrant.Read.All.
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$AppIdOrObjectId,

        [Parameter()]
        [switch]$SkipConnect
    )

    begin {
        Write-Verbose 'Importing Microsoft.Entra module.'
        Import-Module -Name Microsoft.Entra -ErrorAction Stop

        $requiredScopes = @(
            'Application.Read.All'
            'Directory.Read.All'
            'AppRoleAssignment.Read.All'
            'DelegatedPermissionGrant.Read.All'
        )

        if (-not $SkipConnect.IsPresent) {
            $context = $null
            $contextCommand = Get-Command -Name Get-EntraContext -ErrorAction SilentlyContinue
            if ($contextCommand) {
                try {
                    $context = Get-EntraContext -ErrorAction Stop
                }
                catch {
                    Write-Verbose ("Unable to retrieve existing Entra context: {0}" -f $_)
                }
            }

            $scopesSatisfied = $false
            if ($context -and $context.Scopes) {
                $scopesSatisfied = $true
                foreach ($scope in $requiredScopes) {
                    if ($context.Scopes -notcontains $scope) {
                        $scopesSatisfied = $false
                        break
                    }
                }
            }

            if (-not $scopesSatisfied) {
                $connectCommand = Get-Command -Name Connect-Entra -ErrorAction SilentlyContinue
                if (-not $connectCommand) {
                    throw 'Connect-Entra cmdlet was not found. Install Microsoft.Entra module version 1.0.10 or later.'
                }

                Write-Verbose 'Connecting to Microsoft Entra with required scopes.'
                try {
                    if (-not (Get-Command -Name Connect-MgGraph -ErrorAction SilentlyContinue)) {
                        $graphAuthModule = Get-Module -Name Microsoft.Graph.Authentication -ListAvailable |
                            Sort-Object -Property Version -Descending |
                            Select-Object -First 1

                        if ($graphAuthModule) {
                            Write-Verbose ("Importing Microsoft.Graph.Authentication module version {0}." -f $graphAuthModule.Version)
                            Import-Module -Name Microsoft.Graph.Authentication -ErrorAction Stop
                        }
                    }

                    if (-not (Get-Command -Name Connect-MgGraph -ErrorAction SilentlyContinue)) {
                        throw "Connect-Entra requires the Microsoft.Graph.Authentication module. Install it using 'Install-Module -Name Microsoft.Graph.Authentication'."
                    }

                    Connect-Entra -Scopes $requiredScopes -ErrorAction Stop | Out-Null
                }
                catch {
                    if ($_.Exception -and ($_.Exception.Message -match 'BadExpression' -or $_.FullyQualifiedErrorId -eq 'BadExpression')) {
                        throw "Connect-Entra failed because Microsoft.Graph.Authentication is not installed. Install it using 'Install-Module -Name Microsoft.Graph.Authentication'."
                    }

                    throw
                }
            }
            else {
                Write-Verbose 'Existing Microsoft Entra connection has the required scopes.'
            }
        }

        $availableCommands = [ordered]@{
            ApplicationOwner                  = [bool](Get-Command -Name Get-EntraApplicationOwner -ErrorAction SilentlyContinue)
            ServicePrincipalOwner             = [bool](Get-Command -Name Get-EntraServicePrincipalOwner -ErrorAction SilentlyContinue)
            ApplicationPasswordCredential     = [bool](Get-Command -Name Get-EntraApplicationPasswordCredential -ErrorAction SilentlyContinue)
            ApplicationKeyCredential          = [bool](Get-Command -Name Get-EntraApplicationKeyCredential -ErrorAction SilentlyContinue)
            ApplicationFederatedCredential    = [bool](Get-Command -Name Get-EntraApplicationFederatedIdentityCredential -ErrorAction SilentlyContinue)
            ServicePrincipalAppRoleAssignedTo = [bool](Get-Command -Name Get-EntraServicePrincipalAppRoleAssignedTo -ErrorAction SilentlyContinue)
            ServicePrincipalOauth2Grant       = [bool](Get-Command -Name Get-EntraServicePrincipalOauth2PermissionGrant -ErrorAction SilentlyContinue)
        }

        $resourceDisplayNameCache = @{}
    }

    process {
        $escapedIdentifier = $AppIdOrObjectId -replace "'", "''"

        # Validate that the input is a valid GUID before using in filter
        $isGuid = $false
        try {
            $null = [guid]::Parse($AppIdOrObjectId)
            $isGuid = $true
        }
        catch {
            $isGuid = $false
        }

        try {
            Write-Verbose ("Resolving service principal for identifier '{0}'." -f $AppIdOrObjectId)
            if ($isGuid) {
                $servicePrincipal = Get-EntraServicePrincipal -Filter "appId eq '$escapedIdentifier'" -ErrorAction SilentlyContinue |
                    Select-Object -First 1
            }
            else {
                $servicePrincipal = $null
            }

            if (-not $servicePrincipal) {
                Write-Verbose 'Service principal not found by AppId. Trying object id lookup.'
                $servicePrincipal = Get-EntraServicePrincipal -ServicePrincipalId $AppIdOrObjectId -ErrorAction Stop
            }

            Write-Verbose ("Service principal resolved: {0} [{1}]." -f $servicePrincipal.DisplayName, $servicePrincipal.Id)

            $application = Get-EntraApplication -Filter "appId eq '$($servicePrincipal.AppId)'" -ErrorAction Stop |
                Select-Object -First 1

            if (-not $application) {
                throw "Application object for AppId '$($servicePrincipal.AppId)' was not found."
            }

            Write-Verbose ("Application object resolved: {0} [{1}]." -f $application.DisplayName, $application.Id)

            $applicationOwners = @()
            if ($availableCommands.ApplicationOwner) {
                try {
                    $ownerResult = Get-EntraApplicationOwner -ApplicationId $application.Id -All -ErrorAction Stop
                    if ($ownerResult) {
                        $applicationOwners = [array]$ownerResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve application owners: {0}" -f $_)
                }
            }

            $servicePrincipalOwners = @()
            if ($availableCommands.ServicePrincipalOwner) {
                try {
                    $spOwnerResult = Get-EntraServicePrincipalOwner -ServicePrincipalId $servicePrincipal.Id -All -ErrorAction Stop
                    if ($spOwnerResult) {
                        $servicePrincipalOwners = [array]$spOwnerResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve service principal owners: {0}" -f $_)
                }
            }

            $passwordCredentials = @()
            if ($availableCommands.ApplicationPasswordCredential) {
                try {
                    $passwordResult = Get-EntraApplicationPasswordCredential -ApplicationId $application.Id -All -ErrorAction Stop
                    if ($passwordResult) {
                        $passwordCredentials = [array]$passwordResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve password credentials: {0}" -f $_)
                }
            }

            $keyCredentials = @()
            if ($availableCommands.ApplicationKeyCredential) {
                try {
                    $keyResult = Get-EntraApplicationKeyCredential -ApplicationId $application.Id -All -ErrorAction Stop
                    if ($keyResult) {
                        $keyCredentials = [array]$keyResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve key credentials: {0}" -f $_)
                }
            }

            $federatedCredentials = @()
            if ($availableCommands.ApplicationFederatedCredential) {
                try {
                    $fedResult = Get-EntraApplicationFederatedIdentityCredential -ApplicationId $application.Id -All -ErrorAction Stop
                    if ($fedResult) {
                        $federatedCredentials = [array]$fedResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve federated identity credentials: {0}" -f $_)
                }
            }

            $appRoleAssignments = @()
            if ($availableCommands.ServicePrincipalAppRoleAssignedTo) {
                try {
                    $assignmentResult = Get-EntraServicePrincipalAppRoleAssignedTo -ServicePrincipalId $servicePrincipal.Id -All -ErrorAction Stop
                    if ($assignmentResult) {
                        $appRoleAssignments = [array]$assignmentResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve app role assignments: {0}" -f $_)
                }
            }

            $oauth2PermissionGrants = @()
            if ($availableCommands.ServicePrincipalOauth2Grant) {
                try {
                    $grantResult = Get-EntraServicePrincipalOauth2PermissionGrant -ServicePrincipalId $servicePrincipal.Id -All -ErrorAction Stop
                    if ($grantResult) {
                        $oauth2PermissionGrants = [array]$grantResult
                    }
                }
                catch {
                    Write-Verbose ("Unable to retrieve OAuth2 permission grants: {0}" -f $_)
                }
            }

            [array]$resourceAccessDetails = @()
            if ($application.RequiredResourceAccess) {
                [array]$resourceAccessDetails = foreach ($resource in $application.RequiredResourceAccess) {
                    $resourceDisplayName = $null
                    if ($resource.ResourceAppId) {
                        if ($resourceDisplayNameCache.ContainsKey($resource.ResourceAppId)) {
                            $resourceDisplayName = $resourceDisplayNameCache[$resource.ResourceAppId]
                        }
                        else {
                            try {
                                $resourceLookup = Get-EntraServicePrincipal -Filter "appId eq '$($resource.ResourceAppId)'" -ErrorAction SilentlyContinue |
                                    Select-Object -First 1

                                if ($resourceLookup) {
                                    $resourceDisplayName = $resourceLookup.DisplayName
                                }
                            }
                            catch {
                                Write-Verbose ("Unable to resolve display name for resource app {0}: {1}" -f $resource.ResourceAppId, $_)
                            }

                            $resourceDisplayNameCache[$resource.ResourceAppId] = $resourceDisplayName
                        }
                    }

                    [array]$delegatedPermissions = foreach ($access in $resource.ResourceAccess) {
                        if ($access.Type -eq 'Scope') {
                            [PSCustomObject]@{
                                Id   = $access.Id
                                Type = $access.Type
                            }
                        }
                    }

                    [array]$applicationPermissions = foreach ($access in $resource.ResourceAccess) {
                        if ($access.Type -eq 'Role') {
                            [PSCustomObject]@{
                                Id   = $access.Id
                                Type = $access.Type
                            }
                        }
                    }

                    [PSCustomObject]@{
                        ResourceAppId          = $resource.ResourceAppId
                        ResourceDisplayName    = $resourceDisplayName
                        DelegatedPermissions   = $delegatedPermissions
                        ApplicationPermissions = $applicationPermissions
                        ResourceAccess         = $resource.ResourceAccess
                    }
                }
            }

            $webConfiguration = $null
            if ($application.Web) {
                [array]$webRedirectUris = if ($application.Web.RedirectUris) { $application.Web.RedirectUris } else { @() }
                $webConfiguration = [PSCustomObject]@{
                    HomePageUrl           = $application.Web.HomePageUrl
                    RedirectUris          = $webRedirectUris
                    LogoutUrl             = $application.Web.LogoutUrl
                    ImplicitGrantSettings = $application.Web.ImplicitGrantSettings
                }
            }

            [array]$spaRedirectUris = if ($application.Spa -and $application.Spa.RedirectUris) { $application.Spa.RedirectUris } else { @() }
            [array]$publicClientRedirectUris = if ($application.PublicClient -and $application.PublicClient.RedirectUris) { $application.PublicClient.RedirectUris } else { @() }

            $apiConfiguration = $null
            if ($application.Api) {
                [array]$oauth2Scopes = if ($application.Api.Oauth2PermissionScopes) { $application.Api.Oauth2PermissionScopes } else { @() }
                [array]$preAuthApps = if ($application.Api.PreAuthorizedApplications) { $application.Api.PreAuthorizedApplications } else { @() }
                $apiConfiguration = [PSCustomObject]@{
                    Oauth2PermissionScopes      = $oauth2Scopes
                    PreAuthorizedApplications   = $preAuthApps
                    RequestedAccessTokenVersion = $application.Api.RequestedAccessTokenVersion
                }
            }

            [array]$appRoles = if ($application.AppRoles) { $application.AppRoles } else { @() }
            [array]$identifierUris = if ($application.IdentifierUris) { $application.IdentifierUris } else { @() }
            [array]$optionalClaims = if ($application.OptionalClaims) { $application.OptionalClaims } else { @() }
            [array]$tags = if ($servicePrincipal.Tags) { $servicePrincipal.Tags } else { @() }
            [array]$servicePrincipalNames = if ($servicePrincipal.ServicePrincipalNames) { $servicePrincipal.ServicePrincipalNames } else { @() }
            [array]$apiPermissions = if ($application.Api -and $application.Api.Oauth2PermissionScopes) { $application.Api.Oauth2PermissionScopes } else { @() }

            [PSCustomObject]@{
                DisplayName                     = $servicePrincipal.DisplayName
                AppId                           = $servicePrincipal.AppId
                ObjectId                        = $servicePrincipal.Id
                ApplicationObjectId             = $application.Id
                Description                     = $application.Description
                SignInAudience                  = $application.SignInAudience
                PublisherDomain                 = $application.PublisherDomain
                VerifiedPublisher               = $application.VerifiedPublisher
                ServicePrincipalNames           = $servicePrincipalNames
                Tags                            = $tags
                Homepage                        = if ($webConfiguration) { $webConfiguration.HomePageUrl } else { $null }
                RedirectUris                    = if ($webConfiguration) { $webConfiguration.RedirectUris } else { @() }
                LogoutUrl                       = if ($webConfiguration) { $webConfiguration.LogoutUrl } else { $null }
                Web                             = $webConfiguration
                SpaRedirectUris                 = $spaRedirectUris
                PublicClientRedirectUris        = $publicClientRedirectUris
                IdentifierUris                  = $identifierUris
                OptionalClaims                  = $optionalClaims
                AppRoles                        = $appRoles
                RequiredResourceAccess          = $resourceAccessDetails
                Api                             = $apiConfiguration
                ApiPermissions                  = $apiPermissions
                PasswordCredentials             = $passwordCredentials
                KeyCredentials                  = $keyCredentials
                FederatedIdentityCredentials    = $federatedCredentials
                Owners                          = [PSCustomObject]@{
                                                    Application      = $applicationOwners
                                                    ServicePrincipal = $servicePrincipalOwners
                                                }
                AppRoleAssignments              = $appRoleAssignments
                OAuth2PermissionGrants          = $oauth2PermissionGrants
                Notes                           = if ($application.Info) { $application.Info.Notes } else { $null }
                CreatedDateTime                 = $application.CreatedDateTime
                ServicePrincipalCreatedDateTime = $servicePrincipal.CreatedDateTime
                TokenEncryptionKeyId            = $application.TokenEncryptionKeyId
            }
        }
        catch {
            throw "Failed to retrieve application configuration: $_"
        }
    }
}

Back to Top

Download

Please feel free to copy parts of the script or if you would like to download the entire script, simply click the download button. You can download the complete repository in a zip file by clicking the Download link in the menu bar on the left hand side of the page.


Report Issues

You can report an issue or contribute to this site on GitHub. Simply click the button below and add any relevant notes. I will attempt to respond to all issues as soon as possible.

Issue


Back to Top