Omnicit.PIM
0.4.0-preview0001
Entra ID Privileged Identity Management (PIM) Self Activation Commands for Directory Roles, Azure Resources, and Entra ID Groups
Minimum PowerShell version
7.2
See the version list below for details.
Installation Options
Owners
Copyright
(c) Omnicit. All rights reserved.
Package Details
Author(s)
- Omnicit (originally by Justin Grote @justinwgrote)
Tags
PIM Azure EntraID Identity Privileged Windows MacOS Linux
Functions
Connect-OPIM Disable-OPIMAzureRole Disable-OPIMDirectoryRole Disable-OPIMEntraIDGroup 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
PSEditions
Dependencies
-
- Az.Resources (>= 9.0.3)
- Microsoft.Graph.Authentication (>= 2.36.0)
Release Notes
## [0.4.0-preview0001] - 2026-04-19
### Added
- `Connect-OPIM` (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.
- 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 claims-challenge retry via MSAL interactive authentication. Used by `Enable-OPIMDirectoryRole` and `Enable-OPIMEntraIDGroup`.
- `Enable-OPIMMyRole` gains four new switch parameters: `-AllEligible`, `-AllEligibleDirectoryRoles`, `-AllEligibleEntraIDGroups`, `-AllEligibleAzureRoles`. These bypass the TenantMap filter and activate all eligible roles in the selected categories, each requiring interactive ShouldProcess confirmation (supports `-WhatIf`/`-Confirm`).
- `Omnicit.PIM.AzureAssignmentScheduleRequest` type with matching `Format.ps1xml` and `Types.ps1xml` — enables consistent table output for `Enable-OPIMAzureRole` and `Disable-OPIMAzureRole` results.
- `Get-OPIMConfiguration` — reads the TenantMap.psd1 file and returns typed `Omnicit.PIM.TenantConfiguration` objects (one per alias). Supports `-TenantAlias` filter and `-TenantMapPath` override. Alias: `Get-PIMConfig`.
- `Set-OPIMConfiguration` — updates an existing tenant alias entry. Accepts `-TenantId` to change the GUID and pipeline input from `Get-OPIMDirectoryRole`, `Get-OPIMEntraIDGroup`, or `Get-OPIMAzureRole` to replace stored role/group lists. Categories not supplied via pipeline are preserved. Supports `-WhatIf`/`-Confirm`. Alias: `Set-PIMConfig`.
- `Remove-OPIMConfiguration` — removes a single tenant alias from the TenantMap.psd1 file while preserving all other entries. Supports `-WhatIf`/`-Confirm`. Alias: `Remove-PIMConfig`.
- `Export-OPIMTenantMap` (private) — shared PSD1 serializer extracted from `Install-OPIMConfiguration` and reused by `Set-OPIMConfiguration` and `Remove-OPIMConfiguration`.
- `Omnicit.PIM.TenantConfiguration` type with script properties `DirectoryRoleCount`, `EntraIDGroupCount`, and `AzureRoleCount` for concise table display.
### Changed
- **BREAKING** — `Enable-OPIMMyRole` now requires explicit activation intent. Calling it without `-TenantAlias` or an `-AllEligible*` switch emits a non-terminating error (`NoActivationTargetSpecified`) and exits immediately. Previously it silently activated all eligible roles using the current Graph context.
- `Enable-OPIMMyRole` — when `-TenantAlias` is used with a hashtable Config that omits a category key (`DirectoryRoles`, `EntraIDGroups`, `AzureRoles`), a `Write-Warning` is now emitted and that category is skipped instead of activating all eligible roles in it.
- `Enable-OPIMMyRole` — replaced bare `throw` calls (for TenantMap-not-found and alias-not-found errors) with `$PSCmdlet.WriteError()` + `return`, making the function honour `-ErrorAction SilentlyContinue`.
- `Enable-OPIMAzureRole` and `Disable-OPIMAzureRole` — output is now tagged with the `Omnicit.PIM.AzureAssignmentScheduleRequest` type name so the new format file applies.
- **BREAKING** — `Install-OPIMConfiguration` is now a create-only operation. It emits a non-terminating error if the alias already exists and instructs the user to call `Set-OPIMConfiguration` instead.
- **BREAKING** — the `-Force` parameter has been removed from `Install-OPIMConfiguration`. Update semantics (includi
FileList
- Omnicit.PIM.nuspec
- Omnicit.PIM.psd1
- Formats\Omnicit.PIM.DirectoryAssignmentScheduleRequest.Format.ps1xml
- Formats\Omnicit.PIM.GroupAssignmentScheduleRequest.Types.ps1xml
- Omnicit.PIM.psm1
- Formats\Omnicit.PIM.GroupAssignmentScheduleInstance.Format.ps1xml
- en-US\about_Omnicit.PIM.help.txt
- Formats\Omnicit.PIM.DirectoryEligibilitySchedule.Format.ps1xml
- Formats\Omnicit.PIM.DirectoryAssignmentScheduleRequest.Types.ps1xml
- Formats\Omnicit.PIM.GroupCombinedSchedule.Format.ps1xml
- Formats\Omnicit.PIM.DirectoryAssignmentScheduleInstance.Types.ps1xml
- Formats\Omnicit.PIM.DirectoryCombinedSchedule.Format.ps1xml
- Formats\Omnicit.PIM.AzureCombinedSchedule.Types.ps1xml
- Formats\Omnicit.PIM.GroupEligibilitySchedule.Types.ps1xml
- Formats\README.md
- Formats\Omnicit.PIM.AzureAssignmentScheduleRequest.Types.ps1xml
- Formats\RoleAssignmentScheduleRequest.Types.ps1xml
- Formats\Omnicit.PIM.DirectoryEligibilitySchedule.Types.ps1xml
- Formats\Omnicit.PIM.GroupCombinedSchedule.Types.ps1xml
- Formats\Omnicit.PIM.AzureAssignmentScheduleInstance.Types.ps1xml
- Formats\Omnicit.PIM.GroupAssignmentScheduleInstance.Types.ps1xml
- Formats\RoleAssignmentScheduleRequest.Format.ps1xml
- Formats\Omnicit.PIM.AzureEligibilitySchedule.Types.ps1xml
- Formats\Omnicit.PIM.AzureCombinedSchedule.Format.ps1xml
- Formats\Omnicit.PIM.AzureEligibilitySchedule.Format.ps1xml
- Formats\Omnicit.PIM.GroupEligibilitySchedule.Format.ps1xml
- Formats\Omnicit.PIM.DirectoryAssignmentScheduleInstance.Format.ps1xml
- Formats\Omnicit.PIM.TenantConfiguration.Format.ps1xml
- Formats\Omnicit.PIM.GroupAssignmentScheduleRequest.Format.ps1xml
- Formats\Omnicit.PIM.AzureAssignmentScheduleRequest.Format.ps1xml
- Formats\Omnicit.PIM.TenantConfiguration.Types.ps1xml
- Formats\Omnicit.PIM.AzureAssignmentScheduleInstance.Format.ps1xml
- Formats\Omnicit.PIM.DirectoryCombinedSchedule.Types.ps1xml
Version History
| Version | Downloads | Last updated |
|---|---|---|
| 0.4.0 | 10 | 4/21/2026 |
| 0.4.0-previe... | 2 | 4/21/2026 |
| 0.4.0-previe... | 3 | 4/20/2026 |
| 0.4.0-previe... (current version) | 4 | 4/19/2026 |
| 0.3.1 | 5 | 4/16/2026 |
| 0.3.1-previe... | 2 | 4/16/2026 |
| 0.3.1-previe... | 2 | 4/16/2026 |
| 0.3.1-previe... | 2 | 4/16/2026 |
| 0.3.0 | 2 | 4/16/2026 |
| 0.3.0-previe... | 4 | 4/15/2026 |
| 0.3.0-previe... | 4 | 4/14/2026 |
| 0.3.0-previe... | 2 | 4/14/2026 |
| 0.3.0-previe... | 2 | 4/13/2026 |
| 0.3.0-previe... | 4 | 4/2/2026 |
| 0.3.0-previe... | 2 | 4/2/2026 |