Search code examples
powershellazure-powershellazure-cliazure-app-registrationazure-application-registration

How do I create a new Azure app registration and add a scope via PowerShell?


I am trying to create the following using PowerShell:

  • Signs into Entra ID (prompts them in a pop up to sign in, so they can use MFA etc interactively).
  • Create a new application registration called "Connection (Server, Test)", with "Accounts in this organization directory only"
  • Exposes an API with Scope Name of "API.Access", Who can consent? = Admins and users, Admin consent display name = API.Access, Admin consent description = API.Access, State = Enabled. The application ID URL should be whatever is default.
  • When this is done, return to the user the following "The Server Application registration of "Connection (Server, Test) has been created successfully! Note the following details:" followed by the application's Client ID, Tenant ID and the Application ID URL.
  • There should then be a message saying "Creating Client Application... gathering resources..." and a countdown wait of 10 seconds.
  • At the end of the countdown, create a new application registration called "Connection (Client, Test)", with "Accounts in this organization directory only"
  • Create a new secret with an expiry of 24 months and keep the value of the secret in memory.
  • Using the Connection (Client, Test)'s Client ID, add this to Connection (Server)'s application registration as a client application. The authorised scopes should be selected.
  • In the Connection (Client, Test) app registration, an application for authentication needs to be added of type Web, with a Redirect URI of https://oauth.powerbi.com/views/oauthredirect.html. Both "Access tokens (used for implicit flows)" and "ID tokens (used for implicit and hybrid flows)" should be enabled.
  • A message should then appear saying "Success! The applications of Connection (Server, Test) and Connection (Client, Test) have been created. Please make a note of the following details: Server-Test Client ID: (the server test client ID), Server-Test Tenant ID: (server test tenant ID), Client-Test Client ID: (client test client ID), Client-Test Client Secret: (client test secret here)"

Here is my current script which I have hand-written but am getting confused when it comes to setting the scope for the original Server Test app - I have tried this, but the parameters of -Id and -Type (which I would follow in Portal) don't seem to apply in the PS CLI, and also when I need to declare the api:// as the scope, this fails as the Add-AzADAppPermission element isn't working.

Import-Module Az.Accounts
Import-Module Az.Resources

Connect-AzAccount

# create the server application registration
$serverApp = New-AzADApplication -DisplayName "Connection (Server, Test)" -AvailableToOtherTenants $false

# expose an API with details
$scopeName = "API.Access"
$scopeId = (New-Guid).Guid
$apiPermission = Add-AzADAppPermission -ApplicationId $serverApp.ApplicationId -Id $scopeId -Type "Scope" -Permission $scopeName -Description "API Access scope"
$serverApp = Set-AzADApplication -ObjectId $serverApp.ObjectId -IdentifierUris "api://$($serverApp.ApplicationId)" -ApiPermissions $apiPermission

Write-Host "The Server Application registration of Connection (Server, Test) has been created successfully! Note the following details:"
Write-Host "Server-Test Client ID: $($serverApp.ApplicationId)"
Write-Host "Server-Test Tenant ID: $tenantId"
Write-Host "Server-Test Application ID URL: api://$($serverApp.ApplicationId)"

# Creating client application after a delay to mkae sure the svr app has fully deployed
Write-Host "Creating Client Application... gathering resources..."
Start-Sleep -Seconds 10

$clientApp = New-AzADApplication -DisplayName "Connection (Client, Test)" -AvailableToOtherTenants $false
$clientSecret = New-AzADAppCredential -ObjectId $clientApp.ObjectId -EndDate (Get-Date).AddMonths(24)
$secretValue = $clientSecret.SecretText

# setapplication as a client application to the server
New-AzADServicePrincipal -ApplicationId $clientApp.ApplicationId
New-AzADAppPermissionGrant -ObjectId $clientApp.ObjectId -ApiId $serverApp.ApplicationId -ExpiryTime (Get-Date).AddMonths(24) -Scope $scopeName

# add authentication platform for client app
$redirectUri = "https://oauth.powerbi.com/views/oauthredirect.html"
New-AzADAppRedirectUri -ObjectId $clientApp.ObjectId -RedirectUri $redirectUri
Set-AzADApplication -ObjectId $clientApp.ObjectId -ReplyUrls $redirectUri -OAuth2AllowImplicitFlow $true -OAuth2AllowIdTokenImplicitFlow $true

Write-Host "Success! The applications of Connection (Server, Test) and Connection (Client, Test) have been created. Please make a note of the following details:"
Write-Host "Server-Test Client ID: $($serverApp.ApplicationId)"
Write-Host "Server-Test Tenant ID: $tenantId"
Write-Host "Client-Test Client ID: $($clientApp.ApplicationId)"
Write-Host "Client-Test Client Secret: $secretValue"
"

Solution

  • Registering Server App:

    #registering server application
    $serverApp = New-AzADApplication -DisplayName "Connection (Server, Test)" -AvailableToOtherTenants $false
    
    $AppId=$serverApp.AppId
    
    Set-AzADApplication -ApplicationId $serverApp.AppId -IdentifierUris "api://$AppId"
    
    $app = Get-AzAdApplication -ApplicationId "<AppId>"
    
    

    enter image description here

    Exposing an API for Server-App and Registering Client-App

    #exposing an API 
    
    $permissionScop = New-Object Microsoft.Azure.Powershell.Cmdlets.Resources.MSGraph.Models.ApiV10.MicrosoftGraphPermissionScope
    
    $permissionScop.Id = New-Guid
    
    $permissionScop.AdminConsentDescription = "API.Access"
    
    $permissionScop.AdminConsentDisplayName = "API.Access"
    
    $permissionScop.IsEnabled = $true
    
    $permissionScop.Type = "User" 
    
    $permissionScop.UserConsentDescription = "API.Access"
    
    $permissionScop.UserConsentDisplayName = "API.Access"
    
    $permissionScop.Value = "user_impersonation"
    
    
    $api = $app.Api
    #$api.Oauth2PermissionScope = $permissionScop
    $api.Oauth2PermissionScope =$permissionScop
     
    Update-AzADApplication -ApplicationId "<AppId>" -Api $api
    
    

    enter image description here

    Write-Host "The Server Application registration of Connection (Server, Test) has been created successfully! Note the following details:"
    
    Write-Host "Server-Test Client ID: $($serverApp.AppId)"
    
    $context = Get-AzContext
    Write-Output "Tenant ID: $($context.Tenant.Id)"
    
    Write-Host "Server-Test Tenant ID: $tenantId"
    
    Write-Host "Server-Test Application ID URL: api://$($serverApp.AppId)"
    
    # Creating client application after a delay to make sure the svr app has fully deployed
    Write-Host "Creating Client Application... gathering resources..."
    Start-Sleep -Seconds 10
    
    #registering client-app
    
     $displayName = "Connection (Client, Test)"
    
    $redirectUri = "https://oauth.powerbi.com/views/oauthredirect.html"
    
    $newApp = New-AzureADApplication -DisplayName $displayName
    
    Set-AzureADApplication -ObjectId $newApp.ObjectId -ReplyUrls @($redirectUri)
    
    Set-AzureADApplication -ObjectId $newApp.ObjectId -Oauth2AllowImplicitFlow $true
    
    $clientSecret = New-AzADAppCredential -ObjectId $clientApp.ObjectId -EndDate (Get-Date).AddMonths(24)
    $secretValue = $clientSecret.SecretText
    
    New-AzADServicePrincipal -ApplicationId $newApp.AppId
    
    
    

    enter image description here

    Add-AzADAppPermission -ObjectId ObjectIDOfApp -ApiId Resource App ID -PermissionId Permission ID

    enter image description here

    By using powershell, we are not able to grant the admin consent, it can be done by on portal or Azure cli.

    CLI Command az ad app permission admin-consent --id 00000000-0000-0000-0000-000000000000.

    Write-Host "Success! The applications of Connection (Server, Test) and Connection (Client, Test) have been created. Please make a note of the following details:"
    
    
    Write-Host "Server-Test Client ID: $($serverApp.AppId)"
    
    Write-Host "Client-Test Client ID: $($newApp.AppId)"
    
    Write-Host "Client-Test Client Secret: $secretValue"
    
    Write-Output "Tenant ID: $($context.Tenant.Id)"