Omnicit.EntraRBAC.psd1

@{
    RootModule           = 'Omnicit.EntraRBAC.psm1'
    ModuleVersion        = '1.4.0'
    CompatiblePSEditions = @('Core')
    GUID                 = '7b9e4a1c-2d6f-4f3a-9c8b-1e5d0a7c3f42'
    Author               = 'Omnicit AB / Philip Haglund'
    CompanyName          = 'Omnicit'
    Copyright            = '(c) 2026 Omnicit AB'
    Description          = 'Manage Entra ID and Azure RBAC building blocks across tenants: Entra ID groups, PIM, Administrative Units, Entitlement Management, Access Reviews, Azure resources and RBAC, plus a JSON inventory and declarative apply engine.'
    PowerShellVersion    = '7.6'

    RequiredModules = @(
        @{ ModuleName = 'AzAuth'; ModuleVersion = '2.11.0' }
        @{ ModuleName = 'Microsoft.Graph.Authentication'; ModuleVersion = '2.36.0' }
    )

    # Loaded via Update-TypeData in suffix.ps1 (Remove-Module does not clean type data).
    TypesToProcess   = @()
    FormatsToProcess = @('Formats/Omnicit.EntraRBAC.Format.ps1xml')

    FunctionsToExport = @('Add-OERAccessPackageResourceRole','Add-OERAdministrativeUnitMember','Add-OERAdministrativeUnitScopedRole','Add-OERCatalogResource','Add-OERGroupEligibility','Add-OERGroupMember','Connect-OER','Disable-OEREligibleRoleAssignment','Disconnect-OER','Enable-OEREligibleRoleAssignment','Export-OERInventory','Get-OERAccessPackage','Get-OERAccessPackageAssignment','Get-OERAccessPackageAssignmentPolicy','Get-OERAccessPackageResourceRole','Get-OERAccessReviewDefinition','Get-OERAccessReviewInstance','Get-OERAccessReviewInstanceDecision','Get-OERActiveDirectoryRoleAssignment','Get-OERActiveRoleAssignment','Get-OERAdministrativeUnit','Get-OERAdministrativeUnitScopedRole','Get-OERAuthenticationContext','Get-OERCatalog','Get-OERCatalogResource','Get-OERConfiguration','Get-OERDirectoryRoleManagementPolicy','Get-OEREligibleDirectoryRoleAssignment','Get-OEREligibleRoleAssignment','Get-OERGroup','Get-OERGroupEligibility','Get-OERGroupMember','Get-OERGroupPimPolicy','Get-OERInventory','Get-OERManagementGroup','Get-OERRequiredScope','Get-OERResource','Get-OERResourceGroup','Get-OERRoleAssignment','Get-OERRoleDefinition','Get-OERRoleManagementPolicy','Get-OERSubscription','Invoke-OERAccessReviewInstanceDecision','Invoke-OERStructure','New-OERAccessPackage','New-OERAccessPackageApprovalStage','New-OERAccessPackageAssignment','New-OERAccessPackageAssignmentPolicy','New-OERAccessPackageRequestorScope','New-OERAccessPackageRequestorSettings','New-OERAccessReviewDefinition','New-OERAccessReviewStage','New-OERActiveDirectoryRoleAssignment','New-OERActiveRoleAssignment','New-OERAdministrativeUnit','New-OERCatalog','New-OERConfiguration','New-OEREligibleDirectoryRoleAssignment','New-OEREligibleRoleAssignment','New-OERGroup','New-OERPolicyNotificationRule','New-OERResourceGroup','New-OERRoleAssignment','Remove-OERAccessPackage','Remove-OERAccessPackageAssignment','Remove-OERAccessPackageAssignmentPolicy','Remove-OERAccessPackageResourceRole','Remove-OERAccessReviewDefinition','Remove-OERActiveDirectoryRoleAssignment','Remove-OERActiveRoleAssignment','Remove-OERAdministrativeUnit','Remove-OERAdministrativeUnitMember','Remove-OERAdministrativeUnitScopedRole','Remove-OERCatalog','Remove-OERCatalogResource','Remove-OERConfiguration','Remove-OEREligibleDirectoryRoleAssignment','Remove-OEREligibleRoleAssignment','Remove-OERGroup','Remove-OERGroupEligibility','Remove-OERGroupMember','Remove-OERResourceGroup','Remove-OERRoleAssignment','Send-OERAccessReviewReminder','Set-OERAccessPackage','Set-OERAccessPackageAssignmentPolicy','Set-OERAccessReviewDefinition','Set-OERAdministrativeUnit','Set-OERCatalog','Set-OERConfiguration','Set-OERDirectoryRoleManagementPolicy','Set-OERGroup','Set-OERGroupPimPolicy','Set-OERResourceGroup','Set-OERRoleAssignment','Set-OERRoleManagementPolicy','Stop-OERAccessReviewInstance','Test-OERStructure')
    CmdletsToExport   = @()
    VariablesToExport = @()
    AliasesToExport   = @()

    PrivateData = @{
        PSData = @{
            Tags                     = @('EntraID', 'Azure', 'RBAC', 'PIM', 'Identity', 'Governance',
                                          'PSEdition_Core', 'Windows', 'Linux', 'MacOS')
            ProjectUri               = 'https://github.com/Omnicit/Omnicit.EntraRBAC'
            LicenseUri               = 'https://github.com/Omnicit/Omnicit.EntraRBAC/blob/main/LICENSE'
            IconUri                  = 'https://raw.githubusercontent.com/Omnicit/Omnicit.EntraRBAC/main/assets/icon.png'
            RequireLicenseAcceptance = $false
            ReleaseNotes             = '## [1.4.0] - 2026-11-06

Omnicit.EntraRBAC now requires PowerShell 7.6 or later. PowerShell 7.4 and 7.5 reach end of support
on 10 November 2026, and 7.6 is the current long-term support release; a host on 7.4 or 7.5 can
keep using 1.3.1. Windows, Linux and macOS are supported as before, and no command changes. A
tenant named by domain is looked up before any token is requested, and that lookup now also ends
after 30 seconds when the authority sends its response headers and then stalls, failing with
`TenantResolutionFailed` instead of waiting until it is interrupted.

A read that fails now writes an error record and leaves `$null`, not an empty value; the object is
still returned: `RoleAssignments` (`Get-OERResource`, `Get-OERResourceGroup`), `Stages` and
`Decisions` (`Get-OERAccessReviewInstance`), `RoleName` (`Get-OERDirectoryRoleManagementPolicy`).
`Get-OERRoleManagementPolicy` and `Set-OERRoleManagementPolicy` publish a failed lookup as itself and
an ambiguous role as `AmbiguousName`. A role `-CommonRoles` cannot read is an error, not a warning,
and `Get-OERInventory` reports that section unread.

`Invoke-OERStructure -Prune` keeps a group''s last standing owner when the other owners hold, or
are eligible for, ownership through PIM for Groups. It writes the validator''s warnings before
signing in, reports rows a handler wrote before failing, and plans an invalid derived mail alias
as Failed. A reference refused through a rename, an `-Include` or a failed access package entry
writes an error record, so `$?` is false and `-ErrorAction Stop` ends the run.
`New-OERAccessPackage -Catalog` refuses a package of another catalog, and
`Set-OERAccessPackageAssignmentPolicy` a policy read lacking a setting.

Microsoft Graph and Azure Resource Manager now act as one account. Signing in as another account,
`Connect-OER -Force` included, drops the previous account''s Azure token, and an Azure token issued to
another account than the Microsoft Graph token is never cached: the first sign-in and
`Connect-OER -IncludeARM` now refuse it with `ArmAccountMismatch`, as a renewal already did with
`SignInSuperseded`.

A one-time access review now lasts the days it declares; Microsoft Graph ran it for 30 days.
`Set-OERAccessReviewDefinition -DurationInDays` moves a one-time review''s end, never to today or
earlier. An `accessReviews` entry can declare `group` (a name or an id) to review all members of a
group: the export writes it, `Invoke-OERStructure` applies it and refuses a review of another
group, `New-OERAccessReviewDefinition -Group` creates one. The export skips a review whose
reviewers it cannot write back.

'

            Prerelease               = ''
        }
    }
}