Move-PimIdentities
Move each PIM Manager app and job to its own identity
Part of the PIM Manager release - not a standalone download; it runs via the product's own install command or the updater.
Purpose
Moves each PIM Manager app and job of one install from its current identity (system-assigned, or a shared user-assigned identity) to its own user-assigned identity id-pim-<role>, with the same rights, proven, and only then removes the old identity's copied rights.
When to run it
Once per install for the identity naming standard (one user-assigned identity per role, named id-pim-<role>). First without -Apply (the plan, read-only), then -Apply -Role <role> one role at a time. A role whose proof is still pending (a job that has not run since the switch) is finished by running the same command again after that run.
Who may run it
| Kind | Role | Scope | Why |
|---|---|---|---|
| other | The Invardia Support app's session in this window (PIM's REST context) with AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory and GroupMember.ReadWrite.All | the tenant of the install | Reads the old identity's application permission grants, PIM group memberships and directory role assignments, and gives the same to the new identity; removes them from the old one after the proof. |
| azureRbac | Contributor + User Access Administrator | the PIM subscription | Creates the user-assigned identity, attaches it to the container apps and jobs, writes Azure role assignments (Key Vault, AcrPull, the resource group) and Key Vault access policies, starts the database job and the proof run. |
| azureRbac | User Access Administrator (only with -SupportHasRootAccess) | the tenant root | Copies a right the old identity holds at the tenant root (the engine's Reader). Without it that right is a customer step with the exact command. |
What it changes
| Where | Action | What | Permission / role | Scope | Why | Undo |
|---|---|---|---|---|---|---|
| Azure (the install's resource group) | create | the user-assigned managed identity id-pim-<role>, tagged pim-component=<role> | the PIM resource group | One identity per role, named by the standard. | Invoke-PimArm -Method DELETE on the identity (the command is in the run record). | |
| Microsoft Entra ID | grant | every application permission (appRoleAssignments) the old identity holds, given to id-pim-<role> | the same application permissions as the old identity (application permission) | the tenant | The same rights on the new identity before anything switches. | DELETE the assignment on the new identity (the command is in the run record). |
| Microsoft Entra ID | grant | membership of PIM's own groups (grp-pim-*, members/$ref) the old identity is in | member of the same PIM groups | PIM's groups only | The SQL admin group and the other PIM groups the role needs. | Remove the member (the command is in the run record). |
| Microsoft Entra ID | grant | the directory role assignments of the old identity, given to the new one (for example Fabric Administrator for the engine's Power BI reads) | the same directory role | the same directory scope | No regression in the move. | DELETE the directory role assignment (the command is in the run record). |
| Microsoft Entra ID | grant | owner of PIM's own product app registrations (owners/$ref) -- the UPDATER role only, the identity that owns them | owner of the same PIM registrations | PIM's product registrations only | The updater proves and keeps its app-registration ownership as its new identity. | Remove the owner (the command is in the run record). |
| Microsoft Entra ID | grant | the sign-in front's federated credential (federatedIdentityCredentials) on the PIM Manager registration, for the new web identity -- the WEB role only | a federated credential trusting the new identity | the PIM Manager registration | The sign-in front signs in as the web identity, with no secret. | DELETE the credential (the command is in the run record). |
| Azure | grant | every Azure role assignment held directly by the old identity (Key Vault RBAC, AcrPull, Storage Blob Data Contributor for the as-built report, the resource group, the tenant root with -SupportHasRootAccess) | the same Azure role | the same scope | The same rights on the new identity before anything switches. | DELETE the role assignment (the command is in the run record). |
| Azure Key Vault | grant | the old identity's access policy permissions, given to the new identity | the same key / secret / certificate permissions | the vaults of the PIM resource group | Vaults on access policies (not RBAC). | accessPolicies/remove for the new identity (the command is in the run record). |
| The PIM database | grant | the contained database user id-pim-<role>, made by one run of the in-network database job (ca-pim-dbinit) | the role's database roles from the access catalog (for example pim_engine; the updater also db_ddladmin) | the PIM database | The new identity signs in to the database with its own user. | The user stays harmless until the switch; remove it with the database job if wanted. |
| Azure Container Apps | update | each app / job of the role: the new identity attached, the registry pull identity, Key Vault secret references and PIM_ManagedIdentityClientId (and every setting equal to the old client id) switched to it | the PIM apps and jobs of the role | The app / job signs in as its own identity. | Set-PimIdentityMoveSwitch with the old identity (the command is in the run record). | |
| Azure Container Apps | update | one run of the engine job (and of each job in -StartJobRoles) for the proof | the job | Proves the role works as the new identity before any old right is removed. | Nothing to undo: a normal run. | |
| Microsoft Entra ID and Azure | remove | ONLY after the proof: the old identity's copied rights (application permissions, PIM group memberships, directory roles, Azure role assignments, access policies); a shared user-assigned identity is detached from the app and keeps its rights while anything else uses it; a system-assigned identity stays enabled | the old identity | One identity per role; no right left on the identity that no longer runs the role. | Each removal has its exact re-grant command in the run record. |
What it only reads
- the container apps, jobs, user-assigned identities, key vaults, SQL servers and storage accounts of the resource group
- the Azure role assignments of the old and the new identity (at the subscription and every scope above and below it)
- the application permission grants, PIM group memberships and directory role assignments of the old and the new identity
- the new revision / the job runs after the switch (the proof)
Parameters
| Parameter | Required | Default | What it does |
|---|---|---|---|
| -SubscriptionId | yes | The subscription of the PIM install. | |
| -ResourceGroup | yes | The resource group of the PIM install. | |
| -TenantId | no | the session's | The tenant id (names the tenant root management group). |
| -Apply | no | false | Move the roles in -Role. Without it the script only plans. |
| -Role | no | The roles to move with -Apply: web, engine, updater, downlink, publish, requests, mcp, dbinit, asbuilt. | |
| -SupportHasRootAccess | no | false | The Support app holds User Access Administrator at the tenant root of this install. Without it every root right is a customer step. |
| -ExtraScopes | no | More scopes to read the old identity's Azure roles at (for example a registry outside the subscription). | |
| -PimGroupNames | no | More PIM group names whose membership moves (grp-pim-* always does). | |
| -StartJobRoles | no | engine | The roles whose job is started once for the proof. |
| -NoCleanup | no | false | Stop after the proof; the old rights stay. |
| -RootLater | no | false | A right at the tenant root that only the customer can grant does not stop the move: every other right is copied and the switch goes ahead, and the root right stays an open customer step with its command. |
| -NeedOnly | no | From a SHARED identity copy only the rights the role needs (the product's rights map per role); every right left behind is listed as not copied. The SQL admin group goes only to the database job. A shared identity nothing uses any more loses all its rights at its last clean-up. | |
| -LogDir | no | the temp folder\pim-identity-move | Where the plan and the per-role records are written as JSON. |
Preview with -WhatIf
Without -Apply the script is read-only either way. With -Apply -WhatIf it reads everything, prints the plan and, per role, one line for each step it would take (create, grant, switch, prove, remove) -- nothing is written.
Undo
Every run writes a record to -LogDir with each change in order and its exact undo command; a failed run prints them newest first. Nothing old is removed before the proof.
Network
It connects to: login.microsoftonline.com (token), management.azure.com, graph.microsoft.com
How it runs
Part of the PIM Manager release - not a standalone download; it runs via the product's own install command or the updater.
Release 3.0.70
Every script, identity and permission for your security review: PIM Manager