Skip to content

Commit

Permalink
Renamed cmdlet and moved to public folder
Browse files Browse the repository at this point in the history
  • Loading branch information
merill committed Dec 6, 2024
1 parent 956c4ce commit fd9b7f6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 86 deletions.
2 changes: 1 addition & 1 deletion powershell/Maester.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae
'Test-MtCaLicenseUtilization', 'Test-MtCaMfaForAdmin',
'Test-MtCaMfaForAdminManagement', 'Test-MtCaMfaForAllUsers',
"Test-MtCaGroupsRestricted",
"Test-MtCaGap",
"Test-MtCaGap", "Test-MtCaReferencedGroupsExist",
'Test-MtCaMfaForGuest', 'Test-MtCaMfaForRiskySignIn',
'Test-MtCaRequirePasswordChangeForHighUserRisk',
'Test-MtCaSecureSecurityInfoRegistration', 'Test-MtCisaDiagnosticSettings',
Expand Down
81 changes: 0 additions & 81 deletions powershell/internal/Test-MtCaInvalidGroupsAssigned.ps1

This file was deleted.

15 changes: 15 additions & 0 deletions powershell/public/Test-MtCaReferencedGroupsExist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
This test checks if there are any Conditional Access policies that target deleted security groups.

This usually happens when a group is deleted but is still referenced in a Conditional Access policy.

Deleted groups in your policy can lead to unexpected gaps. This may result in Conditional Access policies not being applied to the users you intended or the policy not being applied at all.

To fix this issue:

* Open the impacted Conditional access policy.
* If the group is no longer needed, click Save to remove the referenced group from the policy.
* If the group is still needed, update the policy to target a valid group.

<!--- Results --->

%TestResult%
78 changes: 78 additions & 0 deletions powershell/public/Test-MtCaReferencedGroupsExist.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<#
.Synopsis
Checks if any conditional access policies include or exclude groups that have been deleted.
.Description
Security Groups will be used to exclude and include users from Conditional Access Policies.
Assignments are still visible in the policy definition in Microsoft Graph API even the group is deleted.
This test checks if all groups used in Conditional Access Policies still exist and shows invalid or deleted items.
.Example
Test-MtCaReferencedGroupsExist
.LINK
https://maester.dev/docs/commands/Test-MtCaReferencedGroupsExist
#>

Function Test-MtCaReferencedGroupsExist {
[CmdletBinding()]
[OutputType([bool])]
param ()

Write-Verbose "Running Test-MtCaReferencedGroupsExist"
# Execute the test only when PowerShell Core and parallel processing is supported
if ($PSVersionTable.PSEdition -eq 'Core') {

$testDescription = ""
$Policies = Get-MtConditionalAccessPolicy

$Groups = $Policies.conditions.users.includeGroups + $Policies.conditions.users.excludeGroups | Select-Object -Unique

$GroupsWhichNotExist = [System.Collections.Concurrent.ConcurrentBag[psobject]]::new()
$Groups | ForEach-Object -Parallel {
$Group = $_
$NotExistedGroup = $using:GroupsWhichNotExist
$GraphQueryResult = Invoke-MtGraphRequest -RelativeUri "groups/$($Group)" -ApiVersion beta -ErrorVariable GraphErrorResult -ErrorAction SilentlyContinue
if ([string]::IsNullOrEmpty($GraphQueryResult)) {
$NotExistedGroup.Add($Group) | Out-Null
}
}

$result = ($GroupsWhichNotExist | Measure-Object).Count -eq 0

if ( $result ) {
$ResultDescription = "Well done! All Conditional Access policies are targeting active groups."
} else {
$ResultDescription = "These Conditional Access policies are referencing deleted security groups."
$ImpactedCaGroups = "`n`n#### Impacted Conditional Access policies`n`n | Conditional Access policy | Deleted security group | Condition | `n"
$ImpactedCaGroups += "| --- | --- | --- |`n"
}

$GroupsWhichNotExist | Sort-Object | ForEach-Object {
$InvalidGroupId = $_
$ImpactedPolicies = Get-MtConditionalAccessPolicy | Where-Object { $_.conditions.users.includeGroups -contains $InvalidGroupId -or $_.conditions.users.excludeGroups -contains $InvalidGroupId }
foreach ($ImpactedPolicy in $ImpactedPolicies) {
if ($ImpactedPolicy.conditions.users.includeGroups -contains $InvalidGroupId) {
$Condition = "include"
} elseif ($ImpactedPolicy.conditions.users.excludeGroups -contains $InvalidGroupId) {
$Condition = "exclude"
} else {
$Condition = "Unknown"
}
$Policy = (Get-GraphObjectMarkdown -GraphObjects $ImpactedPolicy -GraphObjectType ConditionalAccess -AsPlainTextLink)
$ImpactedCaGroups += "| $($Policy) | $($InvalidGroupId) | $($Condition) | `n"
}
}
$ImpactedCaGroups += "`n`nNote: Names are not available for deleted groups. If the group was deleted in the last 30 days it may be available under [Entra admin centre - Deleted groups](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/GroupsManagementMenuBlade/~/DeletedGroups/menuId/DeletedGroups).`n`n"

$resultMarkdown = $ResultDescription + $ImpactedCaGroups
Add-MtTestResultDetail -Description $testDescription -Result $resultMarkdown
return $result

} else {
Write-Verbose "PowerShell Core not available, skip the test"
# PowerShell Core not available, skip the test
Add-MtTestResultDetail -SkippedBecause Custom -SkippedCustomReason "Requires PowerShell 7.x or above. This test uses features that are not available in Windows PowerShell (5.x)."
return $null
}
}
8 changes: 4 additions & 4 deletions tests/Maester/Entra/Test-ConditionalAccessBaseline.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
Test-MtCaExclusionForDirectorySyncAccount | Should -Be $true -Because "there is no policy that excludes directory synchronization accounts"
}
It "MT.1035: All security groups assigned to Conditional Access Policies should be protected by RMAU. See https://maester.dev/docs/tests/MT.1035" -Tag "MT.1035" {
Test-MtCaGroupsRestricted | Should -Be $true -Because "there is one or more policy without protection of included or excluded groups"
Test-MtCaGroupsRestricted | Should -Be $true -Because "there are one or more policies without protection of included or excluded groups"
}
It "MT.1036: All excluded objects should have a fallback include in another policy. See https://maester.dev/docs/tests/MT.1036" -Tag "MT.1036", "Warning" {
Test-MtCaGap | Should -Be $true -Because "there is one ore more object excluded without an include fallback in another policy."
Test-MtCaGap | Should -Be $true -Because "there are one or more objects excluded without a corresponding fallback in another policy."
}
It "MT.1038: All assigned group objects should exists. See https://maester.dev/docs/tests/MT.1038" -Tag "MT.1038", "Warning" {
Test-MtCaInvalidGroupsAssigned | Should -Be $true -Because "there is one or more group objects which not exist anymore."
It "MT.1038: Conditional Access policies should not include or exclude deleted groups. See https://maester.dev/docs/tests/MT.1038" -Tag "MT.1038", "Warning" {
Test-MtCaReferencedGroupsExist | Should -Be $true -Because "there are one or more policies relying on deleted groups."
}
Context "License utilization" {
It "MT.1022: All users utilizing a P1 license should be licensed. See https://maester.dev/docs/tests/MT.1022" -Tag "MT.1022" {
Expand Down

0 comments on commit fd9b7f6

Please sign in to comment.