Omnicit.EntraRBAC.psd1

@{
    RootModule           = 'Omnicit.EntraRBAC.psm1'
    ModuleVersion        = '1.1.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.2'

    RequiredModules = @(
        @{ ModuleName = 'AzAuth'; ModuleVersion = '2.9.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-OERActiveRoleAssignment','Get-OERAdministrativeUnit','Get-OERAdministrativeUnitScopedRole','Get-OERAuthenticationContext','Get-OERCatalog','Get-OERCatalogResource','Get-OERConfiguration','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-OERActiveRoleAssignment','New-OERAdministrativeUnit','New-OERCatalog','New-OERConfiguration','New-OEREligibleRoleAssignment','New-OERGroup','New-OERPolicyNotificationRule','New-OERResourceGroup','New-OERRoleAssignment','Remove-OERAccessPackage','Remove-OERAccessPackageAssignment','Remove-OERAccessPackageAssignmentPolicy','Remove-OERAccessPackageResourceRole','Remove-OERAccessReviewDefinition','Remove-OERActiveRoleAssignment','Remove-OERAdministrativeUnit','Remove-OERAdministrativeUnitMember','Remove-OERAdministrativeUnitScopedRole','Remove-OERCatalog','Remove-OERCatalogResource','Remove-OERConfiguration','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-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'
            RequireLicenseAcceptance = $false
            ReleaseNotes             = '## [1.1.0-preview0001] - 2026-09-28

`Invoke-OERStructure -Prune` no longer removes anything because a lookup failed. When a declared
entry cannot be resolved -- a group member, owner or PIM eligibility, an administrative unit member
or scoped role, an access package resource role, or a role assignment under the same `scope` --
nothing in that collection is removed: its undeclared live entries are reported `Skipped`, rather
than removed or `Extra`, with the reason
`prune withheld: declared entry ''<entry>'' could not be resolved`, and the unresolved entry is still
`Failed`. Such a live entry could previously be deleted, PIM eligibility and Azure role assignments
included. A service principal named in `roleAssignments` needs `"principalType": "ServicePrincipal"`
to resolve.

`Test-OERStructure` now warns about an omitted `members`, `scopedRoles`, catalog `resources` or
access package `resourceRoles` key, which still prunes, and `Invoke-OERStructure -Prune` lists them
before it writes anything; set such a key to `null` to leave it untouched. `Get-OERRequiredScope`
lists `RoleManagement.ReadWrite.Directory` for `Set-OERGroup`.

PIM for Groups policies now support approval: `Set-OERGroupPimPolicy` takes `-RequireApproval`,
`-ApproverUser` and `-ApproverGroup`, and a group''s `pimPolicy` accepts `requireApproval` and
`approvers { users[], groups[] }`, which `Get-OERInventory` now exports (`requireApproval` appears
in every exported `pimPolicy` block). Approvers declared by UPN or group name are resolved to object
ids before comparison, in `pimPolicy` and `roleManagementPolicies` alike, so a re-run reports
`Unchanged`; a `roleManagementPolicies` user approver must now be a UPN or object id, since a
display name is reported `Failed`. Earlier versions could resolve the OWNER policy of a group whose
owner policy was not yet listed to its MEMBER policy, so owner settings, a permanent-eligibility
opening included, could land on the member policy: review the member policies of groups onboarded by
an apply run. A refused policy read is now `PimPolicyReadFailed` rather than `PimPolicyNotFound`,
and a group created in the same run gets up to 30 seconds for its policies to appear. During that
wait, a `404 ResourceNotFound` from Microsoft Graph, on the listing of a policy or on the read of
it, counts as a policy not there yet rather than a failed read. `Test-OERStructure` warns about
unknown keys in `groups` and `pimPolicy`.
`Invoke-OERStructure` no longer returns the eligibility request among its results when it adds a
PIM eligibility to a group.

'

            Prerelease               = 'preview0001'
        }
    }
}