Initialize-PimWorkloadPrereqs
Check and fix a workload's prerequisites for PIM Manager
Purpose
Check, and fix, the prerequisites of ONE workload PIM Manager delegates into (Defender XDR, Intune, Power BI, Azure roles, Entra roles) that PIM cannot fix itself.
When to run it
When a prerequisite chip in PIM Manager (template cards, the workload wizards, Discovery and gaps) shows this command for a workload, with your environment's values filled in. PIM checks every prerequisite an API can answer itself every day; this script is for what needs a person with more rights than the engine has. Safe to run again: what is already in place is reported and left alone.
Who may run it
| Kind | Role | Scope | Why |
|---|---|---|---|
| other | delegated Microsoft Graph scopes Application.Read.All and AppRoleAssignment.ReadWrite.All, plus per workload: RoleManagement.Read.Defender (DefenderXdr), DeviceManagementRBAC.Read.All (Intune), Group.ReadWrite.All, GroupMember.ReadWrite.All and RoleManagement.Read.Directory (PowerBI; RoleManagement.ReadWrite.Directory instead with -GrantFabricAdministrator), Organization.Read.All (EntraRoles) | the browser sign-in (first-party public client 'Microsoft Graph Command Line Tools') | What the browser sign-in asks for, for the checks and the fixes of the chosen workload only. A check the caller cannot read (for example without Directory.Read.All, or LicenseAssignment.Read.All for the licence list) is reported as NOT CHECKED, never as passed. |
| other | delegated Azure access (user_impersonation) through the first-party public client 'Microsoft Azure PowerShell' | Azure Resource Manager, plus Fabric and Power BI (PowerBI) and the store (with -SqlServerFqdn) from the same sign-in | Needed for DefenderXdr (Sentinel), AzureRbac, PowerBI (Fabric tenant setting; the Power BI admin API as YOU for the workspace step), to find the engine identity from the hosted tick job, and to record the result in the store. |
| entraRole | Fabric Administrator (signed in as a person) -- or Admin of each workspace | the Power BI workspaces PIM has rows for (PowerBI with -AddEngineToWorkspaces only) | Reads each workspace's users and adds PIM Manager's identity as workspace Admin through the Power BI admin API (GetGroupUsersAsAdmin / AddUserAsAdmin). Power BI accepts that add only from a PERSON's sign-in: it answers HTTP 401 to a service principal, so the Invardia Support session or a certificate identity only reports. A Global Administrator holds the Fabric administrator rights too. Without the admin rights the workspace is reported as not read. |
| entraRole | Privileged Role Administrator | tenant | Granting the engine a missing Graph application permission (DefenderXdr: RoleManagement.ReadWrite.Defender; Intune: DeviceManagementRBAC.ReadWrite.All; EntraRoles: the engine's Graph role map) needs a Privileged Role Administrator or a Global Administrator. So does assigning the directory role Fabric Administrator to the engine identity (PowerBI with -GrantFabricAdministrator). |
| entraRole | Groups Administrator | tenant (PowerBI only) | Creates the Power BI admin-API security group and adds the engine identity to it (a User Administrator works too). |
| entraRole | Fabric Administrator | tenant (PowerBI only) | Reads and changes the Fabric tenant setting 'Service principals can access read-only admin APIs'. Without it the check is NOT CHECKED and the portal step is shown. The setting 'Service principals can access admin APIs used for updates' is never changed by the script: it prints the one instruction for it. |
| entraRole | Power BI Administrator | tenant (PowerBI only) | The former name of Fabric Administrator: older tenants still show it, so the script looks the role up by either name. It is the same role -- nothing extra is granted. |
| azureRbac | User Access Administrator | each Azure scope in your delegation rows and -AzureScope (AzureRbac with -GrantAzureUserAccessAdministrator only; Owner works too) | Assigns User Access Administrator to the engine identity at that scope. |
| azureRbac | Contributor | the subscription of the dedicated Sentinel workspace (DefenderXdr with -EnableSentinel only) | Creates the dedicated Log Analytics workspace, registers the Microsoft.OperationsManagement and Microsoft.SecurityInsights resource providers and enables Microsoft Sentinel on it. |
| azureRbac | Reader | the hosting resource group and the Log Analytics workspaces | Finds the engine identity from the tick job when -EngineObjectId is not given, and reads whether Sentinel is enabled. |
| entraRole | Security Administrator | tenant (DefenderXdr portal step only) | Not used by the script: the script reports the portal step 'activate the Unified RBAC workloads', which a Security Administrator does in the Microsoft Defender portal. |
| other | member of the environment's SQL admin group (only to record the result with -SqlServerFqdn) | the environment's store | Without it nothing is recorded here; press Check again in PIM Manager and PIM records it itself. |
What it changes
| Where | Action | What | Permission / role | Scope | Why | Undo |
|---|---|---|---|---|---|---|
| Microsoft Graph | grant | application permission for the engine identity (app role assignment on Microsoft Graph, POST servicePrincipals/{engine}/appRoleAssignments) -- only the ones missing; a role is granted only when the role map's id is the live id | DefenderXdr: RoleManagement.ReadWrite.Defender; Intune: DeviceManagementRBAC.ReadWrite.All; EntraRoles: the engine's full Graph role map (repository runs only) | tenant (application permissions apply tenant-wide) | The engine assigns the Defender / Intune / Entra roles you delegate through these permissions. | Entra admin center > Enterprise applications > the engine identity > Permissions > remove the permission. |
| Microsoft Graph | create | security group -PowerBiSecurityGroupName (default grp-pim-powerbi-admin-api), only when it does not exist (PowerBI) | tenant | Microsoft's rule for the read-only Power BI admin APIs: the service principal must be in a security group the Fabric tenant setting allows. | Delete the group (first remove it from the Fabric tenant setting). | |
| Microsoft Graph | grant | member of the Power BI admin-API security group: the engine identity (PowerBI) | group membership that the Fabric setting 'Service principals can access read-only admin APIs' allows | the Power BI admin-API security group | Lets the engine call the read-only Power BI admin APIs to manage Power BI workspace access. | Remove the engine identity from the group. |
| Microsoft Fabric | update | tenant setting 'Service principals can access read-only admin APIs' (AllowServicePrincipalsUseReadAdminAPIs): enabled for the group, every group already in it kept (PowerBI) | the Fabric / Power BI tenant | Without it the engine's Power BI admin API calls are refused. | Fabric admin portal > Tenant settings > Admin API settings > remove the group (or disable the setting if the script enabled it). | |
| Microsoft Entra ID | grant | directory role 'Fabric Administrator' (looked up by name in roleManagement/directory/roleDefinitions, never a fixed id) for the engine identity: a PERMANENT, ACTIVE assignment at the directory scope '/' (POST roleManagement/directory/roleAssignments), only when it holds none, read back (PowerBI, OPT-IN with -GrantFabricAdministrator) | Fabric Administrator | tenant (directory scope '/') | PIM Manager gives Power BI workspace roles through the Power BI admin API only, never as a member of a workspace; that API's writes (add / remove a workspace user as admin) need a Fabric Administrator. It is standing privilege, so it is opt-in. | Entra admin center > Roles & admins > Fabric Administrator > Assignments > Active assignments > remove the engine identity. |
| Microsoft Power BI | grant | workspace Admin for the engine identity (POST https://api.powerbi.com/v1.0/myorg/admin/groups/{workspace}/users { identifier = the engine's object id; principalType = App; groupUserAccessRight = Admin }) in every workspace PIM has Power BI rows for and every -WorkspaceId, ONLY where it is not Admin yet (GET .../admin/groups/{workspace}/users first), read back; nobody is ever removed or changed (PowerBI, OPT-IN with -AddEngineToWorkspaces; without it the same table is printed, report only) | Fabric Administrator (or Admin of that workspace), signed in in the browser as a person | each Power BI workspace named by a Power BI Workloads row or -WorkspaceId | PIM Manager gives Power BI workspace roles through the Fabric workspace API (Add Workspace Role Assignment), which only a member or admin of the workspace may call. The Power BI admin API refuses that write to a service principal, so a person adds PIM Manager once per workspace. Run it again when a new workspace gets rows. | Power BI / Fabric portal > the workspace > Manage access > remove PIM Manager's identity (the engine then cannot give roles there any more: POWERBI-ENGINE-NOT-IN-WORKSPACE). |
| Azure Resource Manager | grant | Azure role assignment for the engine identity (Microsoft.Authorization/roleAssignments) at each scope it is missing (AzureRbac, OPT-IN with -GrantAzureUserAccessAdministrator) | User Access Administrator (an Owner or User Access Administrator already held there counts; Reader and Role Based Access Control Administrator are reported, not granted) | each Azure scope in your PIM-Assignments-Azure-Resources rows and -AzureScope | The engine assigns the Azure resource roles you delegate. It is standing privilege, so it is opt-in. | Azure portal > the scope > Access control (IAM) > remove the engine identity's User Access Administrator assignment. |
| Azure Resource Manager | create | dedicated Log Analytics workspace law-sentinel-<suffix> (PerGB2018, 30 days) in -ResourceGroup, or -SentinelWorkspaceId; never PIM's own log workspace (DefenderXdr, OPT-IN with -EnableSentinel; billed per GB ingested) | the hosting resource group | Defender Data Operations roles need Microsoft Sentinel on a workspace. | Delete the workspace (and its Sentinel solution). | |
| Azure Resource Manager | update | resource provider registration Microsoft.OperationsManagement and Microsoft.SecurityInsights on the workspace's subscription, when not registered (-EnableSentinel) | the workspace's subscription | Sentinel cannot be enabled without them. | Unregister the providers (only when nothing else in the subscription uses them). | |
| Azure Resource Manager | create | Microsoft Sentinel on the workspace (Microsoft.SecurityInsights onboardingStates/default) (-EnableSentinel) | the dedicated workspace | Defender Data Operations roles need Microsoft Sentinel on a workspace. | Remove Microsoft Sentinel from the workspace (Microsoft Sentinel > Settings > Remove Microsoft Sentinel). | |
| Azure SQL | update | pim.Settings 'WorkloadPrereqs': this workload's result merged in (a confirmation made in PIM Manager is kept), read back and audited -- only with -SqlServerFqdn and access to the store | the environment's store | PIM Manager shows the result on the template cards and Discovery and gaps. | Press Check again in PIM Manager: PIM records its own result. |
What it only reads
- the engine identity and its application permissions; Microsoft Graph's and the Power BI Service's service principals
- Defender Unified RBAC role definitions and the permission catalog; the Log Analytics workspaces (Azure Resource Graph) and their Sentinel state
- Intune role definitions; the tenant's licences (AAD_PREMIUM_P2)
- the Power BI admin-API group and the groups the engine identity is a member of (its own group list); the Fabric tenant settings
- the engine's Azure role assignments at each scope; the delegation rows in the store (AzureRbac)
- the stored result in pim.Settings 'WorkloadPrereqs' (to merge)
- the engine identity's active assignments of the directory role Fabric Administrator (PowerBI)
- the users of each Power BI workspace PIM has rows for (GET admin/groups/{workspace}/users) and the PIM-Assignments-Workloads rows in the store (PowerBI, with -SqlServerFqdn)
Parameters
| Parameter | Required | Default | What it does |
|---|---|---|---|
| -Workload | yes | DefenderXdr, Intune, PowerBI, AzureRbac or EntraRoles. | |
| -TenantId | yes | Your tenant id; every sign-in and token is checked against it. | |
| -SubscriptionId | no | The hosting subscription (finds the engine identity from the tick job; holds the dedicated Sentinel workspace). | |
| -ResourceGroup | no | The hosting resource group. | |
| -TickJobName | no | ca-pim-tick | The engine's job. When -EngineObjectId is not given, the engine identity is the identity this job signs in as: the user-assigned one its PIM_ManagedIdentityClientId names, else its system-assigned one. |
| -SqlServerFqdn | no | The environment's store; without it (or access to it) the result is not recorded here. | |
| -SqlDatabase | no | PimPlatform | The store's database. |
| -ClientId | no | Automation from the repository only: a certificate identity (with -CertThumbprint). Never shown by PIM Manager. | |
| -CertThumbprint | no | Automation from the repository only: the certificate of -ClientId. | |
| -UseSignedInAccount | no | off | Use the signed-in session of this window (the Invardia Support app session opened by Invardia's connect script; without one, your own browser sign-in). |
| -UseEdge | no | $true | $true opens Microsoft Edge for the sign-in; $false the default browser. |
| -EngineObjectId | no | the tick job's identity | The engine identity's object id (shown in PIM Manager). |
| -EngineAppId | no | The engine application's id, instead of -EngineObjectId. | |
| -EngineCertThumbprint | no | Only with an engine application whose certificate is on this computer: test the Power BI admin API as the engine. | |
| -ConfirmPortalStep | no | Check ids of portal steps you have done; recorded as confirmed (attested, not verified). | |
| -SkipDataOperations | no | off | DefenderXdr: skip the Data Operations / Sentinel checks. |
| -SentinelWorkspaceId | no | DefenderXdr: the Log Analytics workspace to check (and, with -EnableSentinel, enable). | |
| -EnableSentinel | no | off | DefenderXdr, OPT-IN (billed per GB ingested): enable Microsoft Sentinel on a dedicated workspace. |
| -PowerBiSecurityGroupName | no | grp-pim-powerbi-admin-api | PowerBI: the admin-API security group. |
| -AzureScope | no | AzureRbac: more Azure scopes to check. | |
| -GrantAzureUserAccessAdministrator | no | off | AzureRbac, OPT-IN: assign User Access Administrator to the engine where it is missing. |
| -GrantFabricAdministrator | no | off | PowerBI, OPT-IN: assign the Entra directory role Fabric Administrator to the engine identity (permanent, active, directory scope) when it holds none. The Power BI admin API that gives the workspace roles needs it. |
| -AddEngineToWorkspaces | no | off | PowerBI, OPT-IN: add PIM Manager's identity as Admin of every Power BI workspace PIM has rows for (and every -WorkspaceId) where it is not Admin yet, as the person signed in (a Fabric administrator). Never removes anyone. Without it the workspaces are only reported. |
| -WorkspaceId | no | PowerBI: one or more Power BI workspace ids (comma-separated) to check, and with -AddEngineToWorkspaces to add PIM Manager to. PIM Manager fills them in; the store's Power BI rows are read too with -SqlServerFqdn. |
Preview with -WhatIf
Signs in, runs every check of the workload, and prints one "What if:" line per fix it would make (grant a Graph application permission, create the Power BI group, add the engine to it, enable the Fabric setting, assign Fabric Administrator with -GrantFabricAdministrator, add PIM Manager as Admin of a Power BI workspace with -AddEngineToWorkspaces, assign User Access Administrator, create the Sentinel workspace, register the providers, enable Sentinel). A fix that depends on an earlier one not made yet says it cannot be previewed. Nothing is changed and nothing is recorded; the exit code is 0.
Undo
Reverse each change listed above: remove the engine's new application permissions and Azure role assignments, remove the engine from the Power BI group (or delete the group), take the group out of the Fabric setting, remove the engine identity's Fabric Administrator assignment, remove PIM Manager's identity from the Power BI workspaces in Manage access, and remove Sentinel / the dedicated workspace if the script created them.
Network
It connects to: login.microsoftonline.com, graph.microsoft.com, management.azure.com, api.fabric.microsoft.com, api.powerbi.com, <server>.database.windows.net (only with -SqlServerFqdn), localhost (the browser returns the sign-in to a local port on this computer)
Download and run
Run these lines in PowerShell: the first downloads the script into the current folder, the second runs it.
Invoke-WebRequest https://invardia.com/support/pim/Initialize-PimWorkloadPrereqs.ps1 -OutFile Initialize-PimWorkloadPrereqs.ps1
.\Initialize-PimWorkloadPrereqs.ps1 -Workload <Workload> -TenantId <TenantId>To check the download first, compare its SHA-256 with the published one:
SHA-256 e3df9140b17c2274a42fe74cb3a557a1d54fcd54b5760cb11bd76a4a872cd696
Checksums: SHA256SUMS.txt · Version 3.0.70
Before you run it, compare the file's SHA-256 with its line in SHA256SUMS.txt.
Every parameter: Get-Help .\Initialize-PimWorkloadPrereqs.ps1 -Full · Source: Initialize-PimWorkloadPrereqs.ps1
Every script, identity and permission for your security review: PIM Manager