Skip to content

[Work Item] Health Checker: Detect Exchange Well Known Security Groups with incorrect GroupType (non-Universal) #2557

Description

@dpaulson45

Describe the problem

Exchange Well Known Security Groups (e.g., Organization Management, Exchange Servers, Exchange Trusted Subsystem) are required to be Universal Security Groups for RBAC to function correctly. If an administrator or tool changes the group type (e.g., to Global or Domain Local), RBAC breaks and Exchange operations fail with permission errors.

Health Checker currently collects these groups via Get-ExchangeWellKnownSecurityGroupsGet-ExchangeOtherWellKnownObjects but only retrieves WellKnownName, WellKnownGuid, DistinguishedName, RawValue, and SID. GroupType is not collected or checked.

What needs to change

1. Data Collection — Add GroupType property

Get-ExchangeWellKnownSecurityGroups.ps1 currently queries LDAP for objectSid only. It should also retrieve the groupType attribute:

# Current (line 27-28):
$entry = [ADSI]("LDAP://$($wkObject.DistinguishedName)")
$wkObject | Add-Member -MemberType NoteProperty -Name SID -Value (...)

# Proposed: also collect groupType
$groupTypeValue = $entry.Properties["groupType"].Value
$wkObject | Add-Member -MemberType NoteProperty -Name GroupType -Value $groupTypeValue

The groupType attribute is a bitmask:

  • -2147483640 = Universal Security Group (0x80000008) — expected
  • -2147483646 = Global Security Group (0x80000002) — problem
  • -2147483644 = Domain Local Security Group (0x80000004) — problem

2. Analyzer — Check GroupType and warn

In Invoke-AnalyzerExchangeInformation.ps1, after the existing membership checks (lines 315-408), add a new check that verifies all Well Known Security Groups have the correct Universal groupType:

$universalSecurityGroup = -2147483640  # 0x80000008
$wrongTypeGroups = $HealthServerObject.OrganizationInformation.WellKnownSecurityGroups |
    Where-Object { $null -ne $_.GroupType -and $_.GroupType -ne $universalSecurityGroup }

if ($wrongTypeGroups.Count -gt 0) {
    # Display Red warning for each group with wrong type
    foreach ($group in $wrongTypeGroups) {
        # Map groupType value to friendly name
        # Show: "Organization Management - GroupType: Global (expected: Universal)"
    }
}

3. Investigate RBAC impact

Before implementing, test the following scenarios on a lab server and document what breaks:

  • Change Organization Management from Universal to Global — verify RBAC failure behavior
  • Change Exchange Servers from Universal to Global — verify service impact
  • Change Exchange Trusted Subsystem from Universal to Global — verify permission failures
  • Verify whether TokenGroupsGlobalAndUniversal count changes when groups are converted
  • Document exact error messages users see when RBAC breaks from this

4. Pester tests

  • Update GetExchangeWellKnownSecurityGroups.xml mock data to include GroupType property for all 19 groups
  • Add SE Main assertion: "Exchange Security Groups GroupType" = "Passed" (all Universal)
  • Add SE Scenario test with a mock where one or more groups have wrong GroupType
    • Override mock with modified data where Organization Management has GroupType = -2147483646 (Global)
    • Assert Red warning with group name and expected vs actual type
  • Consider adding a dedicated unit test file for the GroupType validation logic

5. Related data collection

Consider whether to also collect and display:

  • member count for key groups (helps identify empty groups)
  • managedBy attribute (identifies who owns the group)
  • Whether the group is in the expected OU/container

Current code references

  • Data Collection: Diagnostics\HealthChecker\DataCollection\OrganizationInformation\Get-ExchangeWellKnownSecurityGroups.ps1 (lines 27-28 — LDAP query)
  • Well Known Object Mapping: Shared\ActiveDirectoryFunctions\Get-ExchangeOtherWellKnownObjects.ps1 (19 groups defined)
  • Analyzer: Diagnostics\HealthChecker\Analyzer\Invoke-AnalyzerExchangeInformation.ps1 (lines 315-408 — membership checks)
  • Mock Data: Diagnostics\HealthChecker\Tests\DataCollection\ExchangeSE\Exchange\GetExchangeWellKnownSecurityGroups.xml (19 groups, no GroupType property)

Additional context

The 19 default Exchange Well Known Security Groups that should all be Universal:
Organization Management, Recipient Management, View-Only Organization Management, Public Folder Management, UM Management, Help Desk, Records Management, Discovery Management, Server Management, Delegated Setup, Hygiene Management, Compliance Management, Exchange Servers, Exchange Trusted Subsystem, Managed Availability Servers, Exchange Windows Permissions, ExchangeLegacyInterop, Security Reader, Security Administrator

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions