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 ""
}