diff --git a/source/tests/Test-AdministrativeAccountCompliance.ps1 b/source/tests/Test-AdministrativeAccountCompliance.ps1 index 4694d37..2a1b0a8 100644 --- a/source/tests/Test-AdministrativeAccountCompliance.ps1 +++ b/source/tests/Test-AdministrativeAccountCompliance.ps1 @@ -8,27 +8,32 @@ function Test-AdministrativeAccountCompliance { begin { # The following conditions are checked: # Condition A: The administrative account is cloud-only (not synced). - # Condition B: The account is assigned only valid licenses (e.g., Microsoft Entra ID P1 or P2). - # Condition C: The administrative account does not have application assignments (only valid licenses are allowed). + # Condition B: The account is assigned a valid license (e.g., Microsoft Entra ID P1 or P2). + # Condition C: The administrative account does not have any other application assignments (only valid licenses). $validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2') $recnum = "1.1.1" + Write-Verbose "Starting Test-AdministrativeAccountCompliance with Rec: $recnum" } process { try { # Retrieve all admin roles + Write-Verbose "Retrieving all admin roles" $adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" } $adminRoleUsers = @() # Loop through each admin role to get role assignments and user details foreach ($role in $adminRoles) { + Write-Verbose "Processing role: $($role.DisplayName)" $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'" foreach ($assignment in $roleAssignments) { + Write-Verbose "Processing role assignment for principal ID: $($assignment.PrincipalId)" # Get user details for each principal ID $userDetails = Get-MgUser -UserId $assignment.PrincipalId -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" -ErrorAction SilentlyContinue if ($userDetails) { + Write-Verbose "Retrieved user details for: $($userDetails.UserPrincipalName)" # Get user license details $licenses = Get-MgUserLicenseDetail -UserId $assignment.PrincipalId -ErrorAction SilentlyContinue $licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" } @@ -36,9 +41,15 @@ function Test-AdministrativeAccountCompliance { # Condition A: Check if the account is cloud-only $cloudOnlyStatus = if ($userDetails.OnPremisesSyncEnabled) { "Fail" } else { "Pass" } - # Condition B and C: Check if the account has only valid licenses - $hasOnlyValidLicenses = ($licenses.SkuPartNumber | ForEach-Object { $validLicenses -contains $_ }) -and (($licenses.SkuPartNumber | ForEach-Object { $validLicenses -notcontains $_ }).Count -eq 0) - $validLicensesStatus = if ($hasOnlyValidLicenses) { "Pass" } else { "Fail" } + # Condition B: Check if the account has valid licenses + $hasValidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -contains $_ } + $validLicensesStatus = if ($hasValidLicense) { "Pass" } else { "Fail" } + + # Condition C: Check if the account has no other licenses + $hasInvalidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -notcontains $_ } + $applicationAssignmentStatus = if ($hasInvalidLicense) { "Fail" } else { "Pass" } + + Write-Verbose "User: $($userDetails.UserPrincipalName), Cloud-Only: $cloudOnlyStatus, Valid Licenses: $validLicensesStatus, Other Applications Assigned: $applicationAssignmentStatus" # Collect user information $adminRoleUsers += [PSCustomObject]@{ @@ -49,13 +60,17 @@ function Test-AdministrativeAccountCompliance { Licenses = $licenseString CloudOnlyStatus = $cloudOnlyStatus ValidLicensesStatus = $validLicensesStatus - ApplicationAssignmentStatus = $validLicensesStatus # Using the same status as ValidLicensesStatus for now + ApplicationAssignmentStatus = $applicationAssignmentStatus } } + else { + Write-Verbose "No user details found for principal ID: $($assignment.PrincipalId)" + } } } # Group admin role users by UserName and collect unique roles and licenses + Write-Verbose "Grouping admin role users by UserName" $uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object { $first = $_.Group | Select-Object -First 1 $roles = ($_.Group.RoleName -join ', ') @@ -64,26 +79,31 @@ function Test-AdministrativeAccountCompliance { $first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } }, CloudOnlyStatus, ValidLicensesStatus, ApplicationAssignmentStatus } - # Identify non-compliant users based on conditions A and B + # Identify non-compliant users based on conditions A, B, and C + Write-Verbose "Identifying non-compliant users based on conditions" $nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object { $_.HybridUser -or # Fails Condition A - $_.ValidLicensesStatus -eq "Fail" # Fails Condition B + $_.ValidLicensesStatus -eq "Fail" -or # Fails Condition B + $_.ApplicationAssignmentStatus -eq "Fail" # Fails Condition C } # Generate failure reasons + Write-Verbose "Generating failure reasons for non-compliant users" $failureReasons = $nonCompliantUsers | ForEach-Object { "$($_.UserName)|$($_.Roles)|$($_.CloudOnlyStatus)|$($_.ValidLicensesStatus)|$($_.ApplicationAssignmentStatus)" } $failureReasons = $failureReasons -join "`n" - $details = if ($nonCompliantUsers) { - "Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + $failureReasons + $failureReason = if ($nonCompliantUsers) { + "Non-Compliant Accounts: $($nonCompliantUsers.Count)" } else { "Compliant Accounts: $($uniqueAdminRoleUsers.Count)" } $result = $nonCompliantUsers.Count -eq 0 $status = if ($result) { 'Pass' } else { 'Fail' } - $failureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | Cloud-Only Status | Valid Licenses Status | Application Assignment Status`n$failureReasons" } else { "N/A" } + $details = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | Cloud-Only Status | Entra ID License Status | Other Applications Assigned Status`n$failureReasons" } else { "N/A" } + + Write-Verbose "Assessment completed. Result: $status" # Create the parameter splat $params = @{