Azure Active Directory Assessment | Part VI

In the previous post, Azure Active Directory Assessment | Part V, we have collected all the information within Conditional Access and the App Registrations. Slowly we have now already a big ton of data to export. But before we do that, we are going to get another thing.
Azure Active Directory Roles#
Azure Active Directory supports two type of roles in the RBAC (Role-Based-Access-Control). The Azure AD Built-in roles or custom roles. These roles have a predefined set of permissions within Azure Active Directory. (link to Microsoft documentation).
If the tenant is using Azure AD Premium 2, there is a possibility that identities are member of a role, but it is not active. You need to activate the role after you login and provide additional security checks like Multi-Factor Authentication. This is called JIT access (Just In Time). Only with an AAD Premium 2 license you will be able to get the assigned roles. Therefore we need to make an exclusion in the script so it will continue even AAD Premium 2 is not present
# setting url
$url = "https://graph.microsoft.com/beta/roleManagement/directory/roleAssignmentSchedules"
try {
$assignedRoles = Invoke-RestMethod -method GET -Headers $header -Uri $url
}
catch {
$webError = $_.Exception
$ErrorDetail = $_
If ($ErrorDetail.ErrorDetails.message -like "*Access token has expired or is not yet valid.*") {
#region connection
# Get an access token for the Microsoft Graph API
do {
$accessToken = (Get-MSALToken -Clientid $ConnectionDetails.ClientId -ClientSecret $connectionDetails.ClientSecret -TenantId $ConnectionDetails.TenantId -ForceRefresh).AccessToken
Start-Sleep -seconds 2
} while (
$accessToken -eq $null
)
$header = @{
'Authorization' = "BEARER $accesstoken"
'Content-type' = "application/json"
}
try {
$assignedRoles = Invoke-RestMethod -method GET -Headers $header -Uri $url
$p2 = $true
}
Catch {
$webError = $_.Exception
$ErrorDetail = $_
}
}
if ($($errordetail.ErrorDetails.Message) -like "*The tenant needs an AAD Premium 2 license.*") {
Write-Output "ERROR: This tenant need AAD Premium 2 License to get roles"
$assignedRoles = $null
$p2 = $false
}
else {
break
}
}
# getting role definitions
$url = "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions"
$roleDefinitions = RunQueryAndProcess
# if AADp2 license is present getting eligible assignments
if ($p2){
$url = "https://graph.microsoft.com/beta/roleManagement/directory/roleEligibilitySchedules"
$eligibleRoles = RunQueryAndProcess
}Now we have all information. Let’s process it.
if ($p2 -eq $false) {
# donothing
}
else {
Write-Output "INFO: Processing all roles ..."
$tableAssignedRoles = @()
$tableAssignedRolesCount = @()
forEach ($role in $assignedRoles.value) {
$assignType = $null
$groupName = $null
$upn = $null
$user = $null
$user = ($Users | Where-Object { $_.id -eq $role.principalId }).UserprincipalName
$roledef = ($roleDefinitions | Where-Object { $_.id -eq $role.roleDefinitionId })
$status = $role.status
$membertype = $role.memberType
$createdDateTime = $role.createdDateTime
$lastchanged = $role.modifiedDateTime
$appScopeId = $role.appScopeId
$startDateTime = $role.scheduleinfo.startDateTime
$expiration = $role.scheduleinfo.expiration.type
$expirationEndTime = $role.scheduleinfo.expiration.endDateTime
$expirationDuration = $role.scheduleinfo.expiration.duration
if ($user) {
$assignType = "User"
$groupName = ""
$upn = $user
}
elseif (!($user)) {
$group = ($groups | Where-Object { $_.id -eq $role.principalId })
if ($group) {
$url = "https://graph.microsoft.com/v1.0/groups/" + $group.id + "/members"
$GroupMembers = RunQueryAndProcess
$members = $GroupMembers.userPrincipalName -Join ","
$assignType = "Group"
$groupName = $group.DisplayName
$upn = $members
}
if (!($group)) {
$url = "https://graph.microsoft.com/v1.0/directoryObjects/" + $Role.principalId
$servicePrincipal = (RunQueryAndProcess).displayName
$assignType = "ServicePrincipal"
$groupName = ""
$upn = $servicePrincipal
}
}
$object = [PSCustomObject]@{
"ID" = $roledef.id
"Rolename" = $roledef.DisplayName
"Description" = $roledef.Description
"isBuiltIn" = $roledef.isBuiltIn
"isEnabled" = $roledef.isEnabled
"Status" = $status
"assignMent" = "Active"
"Membertype" = $membertype
"appScopeId" = $appScopeId
"createdDateTime" = $createdDateTime
"startDateTime" = $startDateTime
"lastChanged" = $lastchanged
"expiration" = $expiration
"expirationEndDateTime" = $expirationEndTime
"expirationDuration" = $expirationDuration
"assignType" = $assignType
"groupName" = $groupName
"User" = $upn
}
$tableAssignedRoles += $object
}
$Count = 0
forEach ($eligiblerole in $eligibleRoles) {
$usermember = $null
$group = $null
$roleName = ($roleDefinitions | Where-Object { $_.id -eq $eligiblerole.roleDefinitionId })
$roleDescription = ($roleDefinitions | Where-Object { $_.id -eq $eligiblerole.roleDefinitionId })
$userMember = ($users | Where-Object { $_.id -eq $eligiblerole.principalId })
$expiration = $eligiblerole.scheduleinfo.expiration.type
$expirationEndTime = $eligiblerole.scheduleinfo.expiration.endDateTime
$expirationDuration = $eligiblerole.scheduleinfo.expiration.duration
if ($usermember) {
$type = "User"
$groupname = ""
$member = $userMember.UserprincipalName
}
elseif (!($usermember)) {
$group = ($groups | Where-Object { $_.id -eq $id.principalId })
if ($Group) {
$type = "Group"
$Groupname = $Group.DisplayName
$Member = ""
}
}
$object = [PSCustomObject]@{
"ID" = $rolename.ID
"RoleName" = $rolename.DisplayName
"Description" = $roleDescription.description
"assignType" = $type
"groupName" = $GroupName
"isBuiltIn" = $rolename.isBuiltIn
"isEnabled" = $rolename.isEnabled
"User" = $member
"assignMent" = "Eligible"
"createdDateTime" = $eligiblerole.createdDateTime
"status" = $eligiblerole.status
"membertype" = $eligiblerole.memberType
"expiration" = $expiration
"expirationEndDateTime" = $expirationEndTime
"expirationDuration" = $expirationDuration
}
$tableAssignedRoles += $object
}
$Unique = $tableAssignedRoles | Sort-Object -Unique "Rolename"
forEach ($Role in $Unique) {
$Countactive = $null
$CountEligible = $null
$CountActive = ($tableAssignedRoles | Where-Object { $_.Rolename -eq $role.rolename -and $_.assignment -eq "Active" }).Count
$CountEligible = ($tableAssignedRoles | Where-Object { $_.Rolename -eq $role.rolename -and $_.assignment -eq "Eligible" }).Count
$object = [PSCustomObject]@{
"ID" = $Role.id
"Rolename" = $role.Rolename
"Description" = $Role.Description
"countActive" = $Countactive
"countEligible" = $CountEligible
}
$tableAssignedRolesCount += $Object
}
Write-Output "INFO: Processing all roles ...[DONE]"
Write-Output ""
}