See my code for adding permissions to a new app registration:
# Define variables
$AppName = "Test Application 5"
$CertSubject = "CN=$AppName"
$StartDate = Get-Date
$EndDate = $StartDate.AddMonths(3) # Adjust certificate validity period as needed
# Create a new Azure AD application
$App = New-AzureADApplication -DisplayName $AppName -IdentifierUris "test9" -HomePage "https://yourapphomepage"
# Generate a new self-signed certificate
$Cert = New-SelfSignedCertificate -Subject $CertSubject -CertStoreLocation "Cert:\CurrentUser\My" -NotBefore $StartDate -NotAfter $EndDate
# Convert the certificate to a base64-encoded string
$CertBytes = [System.Convert]::ToBase64String($Cert.RawData)
$CertValue = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::ASCII.GetBytes($CertBytes))
# Create a new certificate credential for the application
New-AzureADApplicationKeyCredential -ObjectId $App.ObjectId -CustomKeyIdentifier "CertKey" -Type AsymmetricX509Cert -Usage Verify -Value $CertValue -StartDate $StartDate -EndDate $EndDate
# Create a new password credential for the application (secret)
$PasswordCredential = New-AzureADApplicationPasswordCredential -ObjectId $App.ObjectId -CustomKeyIdentifier "PasswordKey" -StartDate $StartDate -EndDate $EndDate
#-------------------------------------------------------------
# Add Permissions
$spForApp = New-AzureADServicePrincipal -AppId $App.AppId -PasswordCredentials @($PasswordCredential)
$appPermissionsRequired = @('offline_access','User.Read.All','Group.Read.All','GroupMember.ReadWrite.All','Directory.Read.All','AuditLog.Read.All')
$targetServicePrincipalName = 'Microsoft Graph'
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$($targetServicePrincipalName)'"
$RoleAssignments = @()
Foreach ($AppPermission in $appPermissionsRequired) {
$RoleAssignment = $targetSp.AppRoles | Where-Object { $_.Value -eq $AppPermission}
$RoleAssignments += $RoleAssignment
}
$ResourceAccessObjects = New-Object 'System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]'
foreach ($RoleAssignment in $RoleAssignments) {
$resourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess"
$resourceAccess.Id = $RoleAssignment.Id
$resourceAccess.Type = 'Role'
$ResourceAccessObjects.Add($resourceAccess)
}
$requiredResourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$requiredResourceAccess.ResourceAppId = $targetSp.AppId
$requiredResourceAccess.ResourceAccess = $ResourceAccessObjects
# set the required resource access
Set-AzureADApplication -ObjectId $App.ObjectId -RequiredResourceAccess $requiredResourceAccess
Start-Sleep -s 1
# grant the required resource access
foreach ($RoleAssignment in $RoleAssignments) {
Write-Output -InputObject ('Granting admin consent for App Role: {0}' -f $($RoleAssignment.Value))
New-AzureADServiceAppRoleAssignment -ObjectId $spForApp.ObjectId -Id $RoleAssignment.Id -PrincipalId $spForApp.ObjectId -ResourceId $targetSp.ObjectId
Start-Sleep -s 1
}
All the permissions were successfully added except for "offline_access".
When I look for the app roles in the command line using:
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
$targetSp.AppRoles
I get a large list of the App Roles in Microsoft Graph. I'm able to find all the app roles except "offline_access". It's like it doesn't exist. But I can add it manually in the azure portal.
Does anyone know how I can target "offline_access"? I tried using the permission ID with no success, but maybe someone knows how to use that. Thank you!
Note that:
Offline_access
is a delegated API permission not application API permission. Hence you have to list it using Oauth2Permissions not AppRoles.
To list the delegated API permissions, use the below command:
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
$targetSp.Oauth2Permissions
To get only the required delegated API permission, execute the below command:
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
$offlineAccessId = $targetSp.Oauth2Permissions | Where-Object { $_.Value -eq 'offline_access' }
You can add offline_access
API permission by using the below code:
# Create a new Azure AD application
$myapp = New-AzureADApplication -DisplayName "RukApptest"
$myappId = $myapp.ObjectId
$MSGraph = Get-AzureADServicePrincipal -All $true | Where-Object { $_.DisplayName -eq "Microsoft Graph" }
# Retrieve the ID of the 'offline_access' permission from Microsoft Graph
$offlineAccessPermission = $MSGraph.Oauth2Permissions | Where-Object { $_.Value -eq 'offline_access' }
$Graph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$Graph.ResourceAppId = $MSGraph.AppId
$Per1 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $offlineAccessPermission.Id,"Scope"
$Graph.ResourceAccess = $Per1
Set-AzureADApplication -ObjectId $myappId -RequiredResourceAccess $Graph