Omnicit.PIM.psd1
|
# # Module manifest for module 'Omnicit.PIM' # # Generated by: Omnicit # # Generated on: 2026-03-25 # @{ # Script module or binary module file associated with this manifest. RootModule = 'Omnicit.PIM.psm1' # Version number of this module. ModuleVersion = '0.4.0' # Supported PSEditions CompatiblePSEditions = @('Core') # ID used to uniquely identify this module GUID = 'ed16ca8d-c9c0-4987-90b9-749edc96ebb8' # Author of this module Author = 'Omnicit (originally by Justin Grote @justinwgrote)' # Company or vendor of this module CompanyName = 'Omnicit' # Copyright statement for this module Copyright = '(c) Omnicit. All rights reserved.' # Description of the functionality provided by this module Description = 'Entra ID Privileged Identity Management (PIM) Self Activation Commands for Directory Roles, Azure Resources, and Entra ID Groups' # Minimum version of the PowerShell engine required by this module PowerShellVersion = '7.2' # Name of the PowerShell host required by this module # PowerShellHostName = '' # Minimum version of the PowerShell host required by this module # PowerShellHostVersion = '' # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # DotNetFrameworkVersion = '' # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # ClrVersion = '' # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module RequiredModules = @( @{ ModuleName = 'Az.Resources'; ModuleVersion = '9.0.3' } @{ ModuleName = 'Microsoft.Graph.Authentication'; ModuleVersion = '2.36.0' } ) # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() # Type files (.ps1xml) to be loaded when importing this module # Disabled: TypesToProcess re-registers type members on every Import-Module -Force but Remove-Module does NOT # clean type data, so the second test file import fails with "member is already present" errors. # Types are loaded via a single Update-TypeData -AppendPath call in the psm1 suffix instead. TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module # Re-enabled: all format targets are Omnicit.PIM.* custom types (no Az-native type overrides), so # the AppendPath precedence issue with Az.Resources no longer applies. # The orphaned RoleAssignmentScheduleRequest override was removed because all Azure functions now # wrap output with Omnicit.PIM.AzureAssignmentScheduleRequest before returning. FormatsToProcess = @('Formats/Omnicit.PIM.Format.ps1xml') # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = @('Connect-OPIM','Disable-OPIMAzureRole','Disable-OPIMDirectoryRole','Disable-OPIMEntraIDGroup','Disable-OPIMMyRole','Disconnect-OPIM','Enable-OPIMAzureRole','Enable-OPIMDirectoryRole','Enable-OPIMEntraIDGroup','Enable-OPIMMyRole','Get-OPIMAzureRole','Get-OPIMConfiguration','Get-OPIMDirectoryRole','Get-OPIMEntraIDGroup','Install-OPIMConfiguration','Remove-OPIMConfiguration','Set-OPIMConfiguration','Wait-OPIMDirectoryRole') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() # Variables to export from this module VariablesToExport = @() # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. AliasesToExport = @('Connect-PIM','Disable-PIMResourceRole','Disable-PIMADRole','Disable-PIMRole','Disable-PIMGroup','unpim','Disable-OPIMMyRoles','Disconnect-PIM','Enable-PIMResourceRole','Enable-PIMADRole','Enable-PIMRole','Enable-PIMGroup','pim','Enable-OPIMMyRoles','Get-PIMResourceRole','Get-PIMConfig','Get-PIMADRole','Get-PIMRole','Get-PIMGroup','Remove-PIMConfig','Set-PIMConfig','Wait-PIMADRole','Wait-PIMRole') # DSC resources to export from this module DscResourcesToExport = @() # List of all modules packaged with this module # ModuleList = @() # List of all files packaged with this module # FileList = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = @('PIM', 'Azure', 'EntraID', 'Identity', 'Privileged', 'Windows', 'MacOS', 'Linux') # A URL to the license for this module. LicenseUri = 'https://github.com/Omnicit/Omnicit.PIM/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/Omnicit/Omnicit.PIM' # A URL to an icon representing this module. IconUri = 'https://raw.githubusercontent.com/Omnicit/Omnicit.PIM/main/assets/icon.png' # ReleaseNotes of this module ReleaseNotes = '## [0.4.0] - 2026-04-21 ### Added - `Get-OPIMCurrentTenantInfo` private helper — resolves the current tenant GUID and display name from the active Graph session. Used by `Install-`, `Set-`, and `Remove-OPIMConfiguration` to enrich the confirmation prompt. - `Install-OPIMConfiguration` now auto-resolves `-TenantId` from the active Graph context when the parameter is omitted. A non-terminating error is emitted when no `-TenantId` is supplied and no active Graph session is available. ### Changed - `Install-OPIMConfiguration`, `Set-OPIMConfiguration`, and `Remove-OPIMConfiguration` now have `ConfirmImpact = ''High''`. The `ShouldProcess` confirmation prompt includes the tenant alias, display name, and resolved GUID, making it clear which tenant is being modified before any write occurs. - `-TenantId` in `Install-OPIMConfiguration` is no longer `[Mandatory]`; it is auto-resolved from `Get-MgContext` when omitted. - PSScriptAnalyzer suppressions added to all six argument-completer classes (`AzureEligibleRoleCompleter`, `AzureActivatedRoleCompleter`, `DirectoryEligibleRoleCompleter`, `DirectoryActivatedRoleCompleter`, `GroupEligibleCompleter`, `GroupActivatedCompleter`). ### Changed - `Write-CmdletError` revamped: new `ErrorRecord` parameter set (pass-through), `InnerException` parameter for exception chaining, `[CmdletBinding()]` added. All public and private functions now use `Write-CmdletError` as the single error-emission entry point. - All variable names across `Convert-GraphHttpException`, `Get-MyId`, `Invoke-OPIMGraphRequest`, `Export-OPIMTenantMap`, and completer classes updated to PascalCase per module code-style rules. (alias `Connect-PIM`) — new public cmdlet to pre-authenticate against Microsoft Graph and optionally Azure. A single browser prompt covers all PIM surfaces (directory roles, Entra ID groups, Azure RBAC). All `Get-/Enable-/Disable-OPIM*` cmdlets call this automatically on first use. - `Disconnect-OPIM` (alias `Disconnect-PIM`) — new public cmdlet to clear all cached session tokens and disconnect from Graph and Azure. - Centralized MSAL-based authentication layer (`Initialize-OPIMAuth`, `Get-OPIMMsalApplication` private helpers). All PIM cmdlets now share a single token-acquisition flow that caches the result and is idempotent when called multiple times in the same session. - ACRS Conditional Access claims-challenge handling moved into `Invoke-OPIMGraphRequest`. A single reactive browser re-prompt is issued when Graph returns a step-up challenge, eliminating repeated browser windows when activating multiple roles in one `Enable-OPIMMyRole` call. - `Invoke-OPIMGraphRequest` private wrapper replaces direct `Invoke-MgGraphRequest` calls throughout the module. Provides bearer-token security (removes raw error records before any processing), ACRS retry, and consistent `Convert-GraphHttpException` error conversion. (ParameterSetName `ByIdentity`) added to all six `Enable-OPIM*` and `Disable-OPIM*` cmdlets. Activates or deactivates a role/group by schedule ID (or schedule `Name` for Azure) without tab completion. For `Disable-*` cmdlets, the ID must correspond to an active schedule instance (from `Get-OPIM* -Activated`). For Azure RBAC the identity is the `Name` property. - `Get-OPIMDirectoryRole`, `Get-OPIMEntraIDGroup`, and `Get-OPIMAzureRole` gain a new `-All` ParameterSet that returns **both** eligible and active schedules for the current user in a single call. `-All` and `-Activated` are mutually exclusive. - `Get-OPIMDirectoryRole` — new `-RoleName` positional parameter (`[Position = 0]`) with tab completion via `DirectoryEligibleRoleCompleter`. Extracts the schedule ID from the trailing `(id)` and performs a dual-search across eligible and active endpoints. - `Get-OPIMEntraIDGroup` — new `-GroupName` positional parameter (`[Position = 0]`) with tab completion via `GroupEligibleCompleter`. Extracts the schedule ID from the trailing `(id)` and performs a dual-search across eligible and active endpoints. - `Get-OPIMAzureRole` — new `-RoleName` positional parameter (`[Position = 0]`) with tab completion via `AzureEligibleRoleCompleter`, and new `-Identity` parameter for direct look-up by schedule `Name`. Both perform dual-search across eligible and active endpoints. - Combined schedule view: When `-All`, `-RoleName`/`-GroupName`/`-Identity` trigger dual-search, all three `Get-OPIM*` cmdlets now return `Omnicit.PIM.*CombinedSchedule` typed objects with a `Status` column (`Eligible` or `Active`) for consistent table output across both result types. - New format/type files for combined schedule views: `Omnicit.PIM.DirectoryCombinedSchedule`, `Omnicit.PIM.GroupCombinedSchedule`, `Omnicit.PIM.AzureCombinedSchedule` — each with a `Status` column in the default table view. ### Performance - **Module load time reduced by ~8 seconds** (~55% of total import time). Consolidated 13 individual `*.Format.ps1xml` files into a single `Omnicit.PIM.Format.ps1xml` and 13 `*.Types.ps1xml` files into a single `Omnicit.PIM.Types.ps1xml`. Previously each file triggered a full format/type table rebuild (~0.49s and ~0.11s per call respectively). - `FormatsToProcess` re-enabled in the module manifest — format data is now loaded natively by PowerShell at zero extra cost. This was previously disabled because `Update-FormatData -PrependPath` was needed to override Az.Resources native types; that override (`RoleAssignmentScheduleRequest`) is no longer needed since all output is wrapped as `Omnicit.PIM.*` custom types. - `suffix.ps1` now loads a single consolidated `Omnicit.PIM.Types.ps1xml` file (1 call to `Update-TypeData`) instead of enumerating and loading 13 individual files (14 calls). `TypesToProcess` remains disabled in the manifest because `Remove-Module` does not clean type data, causing "member already present" errors on `Import-Module -Force`. - Removed orphaned `RoleAssignmentScheduleRequest.Format.ps1xml` and `RoleAssignmentScheduleRequest.Types.ps1xml` — these targeted the native Az `Microsoft.Azure.PowerShell.Cmdlets.Resources.Authorization.Models.Api20201001Preview.RoleAssignmentScheduleRequest` type, but all Azure output is now wrapped with `Omnicit.PIM.AzureAssignmentScheduleRequest`. - Pipeline safety guards: `Enable-OPIMDirectoryRole`, `Enable-OPIMEntraIDGroup`, `Enable-OPIMAzureRole` now skip pipeline objects already tagged as active assignment instances (e.g. objects piped from `Get-OPIM* -All` that have `Status = Active`), emitting a `Write-Verbose` message instead of attempting an activation that would fail. - Pipeline safety guards: `Disable-OPIMDirectoryRole`, `Disable-OPIMEntraIDGroup`, `Disable-OPIMAzureRole` now skip pipeline objects tagged as eligible-only schedules (e.g. objects piped from `Get-OPIM* -All` that have `Status = Eligible`), emitting a non-terminating error instead of attempting a deactivation that would fail. ### Changed - **BREAKING** — `Get-OPIMDirectoryRole -All`, `Get-OPIMEntraIDGroup -All`, and `Get-OPIMAzureRole -All` no longer remove `filterByCurrentUser` / `asTarget()` to list all principals. They now return **both** eligible and active schedules for the **current user**. Admins seeking all-principals data should query the Graph API directly with elevated permissions. - **BREAKING** — `-All` and `-Activated` are now mutually exclusive on all three `Get-OPIM*` cmdlets. Combining them raises a parameter binding error. - `Enable-OPIMDirectoryRole`, `Enable-OPIMEntraIDGroup`, `Enable-OPIMAzureRole` — `-Justification` is now positional `[Position = 1]` and `-Hours` is positional `[Position = 2]`, enabling: `Enable-OPIMDirectoryRole ''Role (id)'' ''Justification'' 4`. ### Fixed - `Get-OPIMDirectoryRole -Activated` no longer applies a post-filter of `assignmentType -eq ''Activated''`. All items returned by `roleAssignmentScheduleInstances` are inherently active assignments; the filter suppressed results when the real Graph API response omitted or differed in that field. - `Get-OPIMEntraIDGroup -All` no longer throws `MissingParameters: The required parameters GroupId or PrincipalId is missing`. The PIM Groups API requires `filterByCurrentUser(on=''principal'')` even when listing all types; this is now preserved. - `Get-OPIMAzureRole -All` no longer throws `InsufficientPermissions`. The `asTarget()` filter is now preserved with `-All`, restricting results to the current user at scope `/`. - `Get-OPIMAzureRole -Activated -Scope ''<specific-scope>''` now returns only instances at that exact scope. Previously, `Get-AzRoleAssignmentScheduleInstance` returned inherited parent-scope instances; these are now filtered out client-side when scope is not `/`. - `Get-OPIMDirectoryRole`, `Get-OPIMEntraIDGroup` — improved `.PARAMETER Filter` documentation with OData examples. Added `.EXAMPLE` blocks for `-Filter` and `-Identity` usage. - `Get-OPIMEntraIDGroup` — `-AccessType` filter now applies correctly when `-All` is combined with `-AccessType member` or `-AccessType owner`. Previously the filter was silently ignored in `-All` mode. - `Get-OPIMAzureRole` — removed `[Alias(''Id'')]` from the `-Scope` parameter. PowerShell''s prefix-matching treated `Id` as an abbreviation of `-Identity`, causing "Parameter set cannot be resolved" errors when `-Identity` was specified alongside the default `$Scope = ''/''` binding. - `Get-OPIMAzureRole` — `Add-Member -NotePropertyName Status` now uses `-Force` to prevent "Cannot add a member with the name ''Status'' because a member already exists" errors when the same object is processed more than once (e.g. across multiple pipeline invocations). - `Get-OPIMAzureRole` dual-search now correctly separates the `-Name` (Get parameter set) and `-Filter` (List parameter set) calls to `Get-AzRoleEligibilitySchedule` and `Get-AzRoleAssignmentScheduleInstance`. These are mutually exclusive parameter sets in Az.Resources; previously passing both parameters caused a parameter binding error. — wraps `Invoke-MgGraphRequest` for PIM activation POST requests with automatic ACRS' # Prerelease string of this module Prerelease = '' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false # External dependent modules of this module # ExternalModuleDependencies = @() } # End of PSData hashtable } # End of PrivateData hashtable # HelpInfo URI of this module # HelpInfoURI = '' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' } |