public/Invoke-EntraIdGroupDesiredState.ps1

<#
.SYNOPSIS
Invokes the desired state configuration for Entra ID groups based on JSON configuration files.

.DESCRIPTION
This function processes JSON configuration files to ensure that Entra ID groups are created or updated to match the desired state. It validates group properties such as membership type, description, members, owners, and whether the group is assignable to roles.

.PARAMETER Path
The path to the directory containing JSON configuration files for groups.

.EXAMPLE
Invoke-EntraIdGroupDesiredState -Path "C:\Configs\Groups"

.NOTES
Author: AzureStackNerd
Date: 11 September 2025
#>


function Invoke-EntraIdGroupDesiredState {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory)]
        [string]$Path
    )

    Test-GraphAuth
    # Get all JSON configuration files in the specified path
    $files = Get-ChildItem -Path $Path -Include *.json, *.jsonc -File -Recurse | Sort-Object Name

    foreach ($file in $files) {
        Write-Verbose "Processing file: $($file.FullName)"
        # Read the group object from the JSON/JSONC file, removing comment lines
        $rawContent = Get-Content -Path $file.FullName -Raw
        # Remove single-line comments (// ...)
        $rawContent = $rawContent -replace '(?m)^\s*//.*$', ''
        # Remove block comments (/* ... */)
        $rawContent = $rawContent -replace '(?s)/\*.*?\*/', ''
        $json = $rawContent | ConvertFrom-Json
        foreach ($group in $json) {
            $groupName = $group.Name
            $groupMembershipType = $group.GroupMembershipType
            $description = $group.description
            $members = $group.members
            $owners = $group.owners
            $isAssignableToRole = $group.IsAssignableToRole

            $params = @{
                DisplayName         = $groupName
                GroupMembershipType = $groupMembershipType
                Description         = $description
                Owners              = $owners
                IsAssignableToRole  = $isAssignableToRole
                Members             = $members
            }

            if (!$owners) {
                Write-Host "Skipping group '$groupName' as it has no owners defined."
                continue
            }

            Set-EntraIdGroup @params
        }
    }
}