Omnicit.EntraRBAC.psd1

@{
    RootModule           = 'Omnicit.EntraRBAC.psm1'
    ModuleVersion        = '1.1.1'
    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-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'
            RequireLicenseAcceptance = $false
            ReleaseNotes             = '## [1.1.1-preview0004] - 2026-10-03

`Get-OERInventory` and `Export-OERInventory` no longer write a collection they could not read as an
empty one. When the read of an access package''s resource role bindings or of a catalog''s resources
fails -- refused, throttled or otherwise failed -- the document carries `"resourceRoles": null` or
`"resources": null`, which `Invoke-OERStructure` leaves untouched, and the `InventoryPartial` error
names the package or catalog. Earlier versions wrote `[]`, and applying that export with `-Prune`
removed every binding or resource of the package or catalog. A failed read of the catalogs, of a
catalog''s access packages, of their assignment policies or of the names their bindings are written
under is now reported through `InventoryPartial` too, and `schema.json` accepts `null` for
`resources` and `resourceRoles`. When the names an access package''s bindings are written under
cannot be read, a group''s binding is written under the group''s object id instead of the name the
catalog recorded, which can name another group after a rename.

A lookup that fails is now reported as that failure, not as a missing object, in the lookups named
here. When the read behind a group, catalog, application or catalog resource name is refused,
throttled or answered with a server error, the cmdlets that resolve one no longer report
`GroupNotFound`, `CatalogNotFound`, `ApplicationNotFound` or `CatalogResourceNotFound`. The same
holds for the user, group, catalog and assignment policy lookups behind the approval, requestor and
review cmdlets, for the definition lookup of `Remove-OERAccessReviewDefinition` and
`Set-OERAccessReviewDefinition`, and for an unreadable Tenant Profile in `Invoke-OERStructure`. Only
a name that matches nothing is not found. `Add-OERGroupEligibility` no longer says a group is not
onboarded when its policy could not be read: it proceeds and Microsoft Graph enforces the policy.
`Add-OERCatalogResource` adds nothing when its check for an existing resource fails, and warns,
returning nothing, when a resource it added cannot be read back. The five access review instance
cmdlets keep `AccessReviewDefinitionResolveFailed`, now a `ReadError` (was `ObjectNotFound`) whose
message carries the cause.

A name that several objects share is now refused with `AmbiguousName`, naming the candidates, where
earlier versions acted on the first match: an access review definition
(`Remove-OERAccessReviewDefinition -DisplayName` could delete, and `Set-OERAccessReviewDefinition`
overwrite, a definition other than the one meant), an assignment policy of an access package, a
resource role of a catalog resource (`Add-OERAccessPackageResourceRole`), and a subscription or
management group display name in the Azure cmdlets (reported as `InvalidScope`, or
`ManagementGroupNotFound` by `Get-OERSubscription`, as a name that does not exist already is).
`Invoke-OERStructure` reports such an entry `Failed` and writes nothing for it; a binding whose
resource name can identify more than one resource, or only a group outside the catalog, is `Failed`
too, and the package''s binding prune is withheld.

An administrative unit''s scoped roles are no longer removed under `-Prune` when the directory role
names cannot be read: the unit is `Failed` and nothing is removed, where earlier versions removed
every scoped role declared by name. `Get-OERInventory` writes an access review whose package or
policy name cannot be read by id and names it in `InventoryPartial`; one whose package or policy no
longer exists is written by id with nothing reported and no stray error records. An administrative
unit whose directory role names cannot be read is exported with `"scopedRoles": null` and named in
`InventoryPartial`.

Lookups of principals, PIM policy approvers and Azure role definitions still report a failed read
as not found (`PrincipalNotFound`, `ApproverNotFound`, `RoleDefinitionNotFound`).

'

            Prerelease               = 'preview0004'
        }
    }
}