New-InvardiaSupportApp
Create, update, rotate, disable, enable or remove the Invardia Support app in your own tenant
Purpose
Invardia support connects to your tenant only when you ask for help, as an app registration that you own. This script creates that single-tenant app ("Invardia Support", found by its InvardiaSupport tag; an app with the earlier name "Invardia Support for SecurityInsight - PIM Manager (customer request-based only)" is renamed on the next Create or NewSecret run), gives it the Microsoft Graph application permissions and Azure roles of the access level you choose (Troubleshoot = read only; Setup = what the products' setup scripts need to install, repair and upgrade unattended), creates a Conditional Access policy (off by default) that limits the app to Invardia's support IP, and prints a short-lived client secret once for you to store in the customer portal. Run again, it adds what is missing and removes what the chosen level does not need; -Action NewSecret / Disable / Enable / Remove manage the app afterwards.
When to run it
When you want Invardia support to look inside your tenant (Troubleshoot) or to run the products' setup for you (Setup); again to rotate the secret, to switch the app off between support cases, or to remove it.
Who may run it
| Kind | Role | Scope | Why |
|---|---|---|---|
| entraRole | Privileged Role Administrator or Global Administrator | Tenant | Grants admin consent for Microsoft Graph application permissions (app role assignments) and creates the app registration. Signs in through the browser with the Azure CLI (or Azure PowerShell / Graph Command Line Tools) public client; delegated scopes asked: Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, and with Conditional Access or -Action Remove also Policy.ReadWrite.ConditionalAccess and Policy.Read.All. |
| azureRbac | Owner or User Access Administrator | Each subscription in -SubscriptionIds, resource group in -ResourceGroupIds, key vault in -KeyVaultIds and -HubVnetId | Assigns the Azure roles of the chosen level to the app. Only needed when you name Azure scopes (and for -Action Remove). A role it cannot assign does not stop the run: it is listed with the fix and the script exits 1. |
| entraRole | Exchange Administrator or Global Administrator | Tenant (only with -ExchangeMailbox or -Action RemoveExchange) | Creates (or removes) the Exchange role group "Invardia Support Mail Setup" and registers the app in Exchange Online. One more browser sign-in, with the Exchange Online PowerShell module's own public client (Microsoft Exchange REST API Based Powershell); no module is installed. |
| azureRbac | User Access Administrator (or Owner) | Tenant root management group (only with -TenantRoot) | Assigns User Access Administrator at the tenant root to the app, for SecurityInsight collecting from the whole tenant. A Global Administrator gets it with Entra ID > Properties > Access management for Azure resources = Yes. Only when your organisation approves it (it is recorded in the Invardia portal); -Action RemoveTenantRoot removes it again. |
What it changes
| Where | Action | What | Permission / role | Scope | Why | Undo |
|---|---|---|---|---|---|---|
| Entra ID | create | App registration "Invardia Support" (single tenant, tags InvardiaSupport, InvardiaSupport:Access=<level>, InvardiaSupport:Products=<products>) and its service principal (assignment required, hidden) | Your tenant | The identity Invardia support signs in as - owned by you, visible in your sign-in logs under a fixed name. | -Action Remove deletes the app and its service principal; -Action Disable switches its sign-in off and keeps every grant. | |
| Entra ID | update | The display name of an existing app (found by its InvardiaSupport tag) and of its service principal, when it is not -DisplayName ("Invardia Support") - -Action Create and NewSecret only | The app only | The naming convention (owner 2026-10-14): the full name where people read it. Before 2026.10.18b the app was called "Invardia Support for SecurityInsight - PIM Manager (customer request-based only)". Its ids, permissions, tags and secret do not change. | Run again with -DisplayName '<the earlier name>', or rename it in Entra ID > App registrations > the app > Branding & properties. | |
| Entra ID | update | The app's own owners: its service principal is made owner of the app | The app only | The app renews its own secret (ring 2 only after your approval by email); with Application.ReadWrite.OwnedBy it can change only itself and apps it created. | Remove the service principal from the app's owners, or -Action Remove. | |
| Microsoft Graph | grant | Application permissions (admin consent), both levels | Directory.Read.All, Application.Read.All, User.Read.All, Group.Read.All, RoleManagement.Read.All, RoleManagementPolicy.Read.Directory, RoleEligibilitySchedule.Read.Directory, RoleAssignmentSchedule.Read.Directory, PrivilegedAccess.Read.AzureADGroup, Application.ReadWrite.OwnedBy; at every level also PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup, PrivilegedAssignmentSchedule.Remove.AzureADGroup, PrivilegedEligibilitySchedule.ReadWrite.AzureADGroup, PrivilegedEligibilitySchedule.Remove.AzureADGroup and RoleManagementPolicy.Read.AzureADGroup (the products' SQL admin groups are role-assignable; their members are managed as PIM for Groups assignments; never removed by a re-run) | Tenant | Read the configuration the products themselves read; renew its own secret (OwnedBy covers only itself and apps it creates). | -Action Remove, or revoke the permission in Entra ID > Enterprise applications > the app > Permissions. |
| Microsoft Graph | grant | Application permissions for PIM Manager (with -Products PimManager) | Domain.Read.All, AdministrativeUnit.Read.All, AccessReview.Read.All, RoleManagementPolicy.Read.AzureADGroup, PrivilegedEligibilitySchedule.Read.AzureADGroup, PrivilegedAssignmentSchedule.Read.AzureADGroup | Tenant | What PIM Manager reads. | Run again without PimManager in -Products (a downgrade: needs -Force), or -Action Remove. |
| Microsoft Graph / Defender | grant | Application permissions for SecurityInsight (with -Products SecurityInsight) | Graph: Device.Read.All, AuditLog.Read.All, Policy.Read.All, IdentityRiskyUser.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, ThreatHunting.Read.All; Microsoft Threat Protection: AdvancedHunting.Read.All; WindowsDefenderATP: Machine.Read.All, Vulnerability.Read.All, Software.Read.All, SecurityRecommendation.Read.All (skipped when that API has no service principal in the tenant) | Tenant | What SecurityInsight reads. | Run again without SecurityInsight in -Products (a downgrade: needs -Force), or -Action Remove. |
| Microsoft Graph | grant | Application permissions at the Setup level (-Access Setup) | Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, DelegatedPermissionGrant.ReadWrite.All, Group.Create, Group.ReadWrite.All, GroupMember.ReadWrite.All; with PimManager also RoleManagement.ReadWrite.Directory, PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup and PrivilegedAssignmentSchedule.Remove.AzureADGroup | Tenant | The products' setup scripts run through this app: they create and update the products' app registrations (also ones an earlier install made), grant the products' managed identities their API permissions and consent their sign-in scopes; PIM Manager's role-assignable SQL admin group needs Group.Create + RoleManagement.ReadWrite.Directory, and - when that group is managed by PIM for Groups - the two PrivilegedAssignmentSchedule permissions to remove a member (owner 2026-10-18). AppRoleAssignment.ReadWrite.All has no narrower alternative. | -Access Troubleshoot -Force revokes them; or -Action Remove. |
| Microsoft Graph | remove | Application permissions the chosen level and products do not need | The app only | Keeps the app at exactly the chosen level. Without -Access / -Products the level and products the app already has are kept; a downgrade needs -Force (or -Confirm). | Run again with the higher -Access / more -Products. | |
| Exchange Online | grant | Application permission Exchange.ManageAsApp (admin consent) - only with -ExchangeMailbox | Office 365 Exchange Online: Exchange.ManageAsApp | Tenant | Lets support run Exchange admin cmdlets as the app over the Exchange admin REST endpoint, to create the products' Office 365 shared mailbox and scope Mail.Send to it. On its own it gives no Exchange rights (every cmdlet answers 403): the role group below does. Never part of the standing Setup level; a re-run without the switch keeps it until -Action RemoveExchange. | -Action RemoveExchange revokes it (or -Action Remove). |
| Exchange Online | create | The app registered in Exchange Online (New-ServicePrincipal) and the custom role group "Invardia Support Mail Setup" holding exactly the roles Mail Recipient Creation + Role Management, with the app as member - only with -ExchangeMailbox. A role group of that name with other roles is reported and never changed. | Exchange roles: Mail Recipient Creation, Role Management | Your Exchange organization | Mail Recipient Creation creates the shared mailbox; Role Management scopes Application Mail.Send to that one mailbox for the products' identities. Role Management can grant any Exchange role, so the rights are time-boxed: take them away once the mailbox is set up. The app's tag InvardiaSupport:Exchange=<date> shows since when it has them. | -Action RemoveExchange: the app leaves the role group and the role group is removed (kept, with a warning, when someone else is in it); -Action Remove does the same before it deletes the app. The app's bare Exchange registration (no role) is kept. The shared mailbox and its scoped Mail.Send stay as the products set them up. |
| Azure | grant | Contributor and User Access Administrator | Contributor, User Access Administrator | Each subscription in -SubscriptionIds (Setup only) | The products' setup creates its own resource groups and grants its own identities. This is owner-level access to those subscriptions: keep the secret in Invardia's portal only and use the Conditional Access lock. | -Access Troubleshoot -Force removes them on the scopes named, or -Action Remove (every subscription you can see and the tenant root). |
| Azure | grant | Reader | Reader | Tenant root management group (with -TenantRoot, Setup only) | Read access to the whole tenant's Azure resources for support (owner 2026-11-09: Reader at the root, not User Access Administrator). -Action RemoveTenantRoot keeps it. | -Action Remove, or delete the role assignment at the tenant root. |
| Azure | grant | User Access Administrator | User Access Administrator | Tenant root management group (with -TenantRoot, Setup only) | SecurityInsight collecting from the whole tenant: its engine gets Reader there. Only when your organisation approves it (it is recorded in the Invardia portal); -Action RemoveTenantRoot removes it again. | -Action RemoveTenantRoot (removes only the app's own User Access Administrator at the root), -Action Remove, or delete the role assignment at the tenant root. |
| Azure | remove | User Access Administrator (the app's own assignment) | User Access Administrator | Tenant root management group (-Action RemoveTenantRoot) | Owner 2026-11-09 (ROOT-RIGHTS-1): User Access Administrator at the tenant root needs the customer's approval (recorded in the Invardia portal); when it is withdrawn the app keeps only Reader there. Reader is made sure first (read back); no other right, scope or principal is touched. | Run the script again with -Access Setup -TenantRoot. |
| Azure | grant | Roles on the resource groups in -ResourceGroupIds | Setup: Contributor + Role Based Access Control Administrator WITH a condition (it may only assign or remove AcrPull, Reader, Log Analytics Reader, Monitoring Metrics Publisher, Contributor, Container Apps Jobs Operator, Storage Blob/Queue/Table Data Contributor, Key Vault Secrets User, Key Vault Reader, Cognitive Services OpenAI User, to service principals only). Troubleshoot: Reader + Log Analytics Reader | Each resource group named | Setup: install and repair the product there and grant its managed identities their roles - never Owner (the condition). Troubleshoot: read the resources and logs. | Run again at the other level (removes the roles that level does not include), or -Action Remove. |
| Azure | grant | Roles on the key vaults in -KeyVaultIds | Setup: Key Vault Secrets Officer (+ Key Vault Crypto Officer with -PimMspManagingTenant). Troubleshoot: Key Vault Reader (metadata only, no secret values) | Each key vault named | Setup: the products keep their secrets there. Troubleshoot: see which secrets exist and when they expire. | Run again at the other level, or -Action Remove. |
| Azure | grant | Network Contributor | Network Contributor | The VNet in -HubVnetId (Setup only) | Products installed with private networking peer to your hub VNet. | -Action Remove, or delete the role assignment on the VNet. |
| Azure | remove | Role assignments of the app on the scopes you named that the chosen level does not include | Only the scopes named in this run; a scope whose assignments cannot be read is never treated as empty | Keeps the app at exactly the chosen level. | Run again at the higher level. | |
| Entra ID Conditional Access | create | Named location "Invardia Support (Morten Knudsen)" = 172.205.146.248/32 (-SupportIp), not trusted | Tenant | The one address Invardia support connects from. | -Action Remove deletes it; or delete it in Entra ID > Conditional Access > Named locations. | |
| Entra ID Conditional Access | create | Policy "CA701-Prod-WorkloadIdentities-InvardiaSupport-AnyPlatform-NonTrustedLocations-Block" for this app only: block its sign-in from every location except the named location. Created OFF (disabled) unless -ConditionalAccessState says otherwise; a re-run keeps the state of a policy it finds | This app's service principal | When you switch it on, the app can only sign in from Invardia's support IP. Needs Microsoft Entra Workload ID Premium licences; without them the policy cannot be saved and the script says so. -NoConditionalAccess skips it. | -Action Remove deletes it; or delete it in Entra ID > Conditional Access. | |
| Entra ID | create | A new client secret on the app; every older secret of the app is removed first | The app only | The credential you store in the portal (portal.invardia.com > Remote support). Lifetime by -Ring: 2 = 90 days (customers; you approve each renewal by email), 3 = 1 day (one-off setup), 1 = 2 years (Invardia's own tenants); -SecretDays overrides. Printed once, never written to the transcript. -NoSecret skips it. | -Action NewSecret replaces it; delete it in Entra ID > App registrations > the app > Certificates & secrets, or -Action Remove. | |
| Entra ID | update | The service principal's sign-in (accountEnabled) - -Action Disable / Enable only | The app only | Switch Invardia's access off between support cases without losing the grants. | The other action. | |
| Entra ID / Azure | remove | -Action Remove: the app's role assignments on every subscription you can see, the subscriptions named and the tenant root; the Conditional Access policy and named location; the app registration and its service principal | Everything this script created (found by its tag and fixed names) | Removes Invardia's access completely. | Run the script again to create the app anew (a new client id and secret). |
What it only reads
- Your sign-in token's tenant and scopes (to refuse a wrong tenant and to know whether one more sign-in is needed)
- The existing Invardia Support app (by name and its InvardiaSupport tag), its owners, its granted permissions and its secrets' key ids
- The service principals of Microsoft Graph, Microsoft Threat Protection and WindowsDefenderATP (the permission ids)
- Azure role definitions, and the app's role assignments at, above and below the scopes named (Remove: every subscription you can see)
- Conditional Access named locations and policies (to find its own by name)
- With -ExchangeMailbox / -Action RemoveExchange: the service principals Exchange knows, the role group "Invardia Support Mail Setup" and its members
Parameters
| Parameter | Required | Default | What it does |
|---|---|---|---|
| -TenantId | yes | Your tenant id (a GUID). The sign-in must be to this tenant, or the script stops before changing anything. | |
| -Action | no | Create | Create (or update) | NewSecret (a new secret; permissions unchanged unless -Access / -Products is given) | Disable | Enable | Remove | RemoveExchange (takes the -ExchangeMailbox rights away again) | RemoveTenantRoot (makes sure the app holds Reader at the tenant root, then removes ONLY its own User Access Administrator there; both read back; for an organisation that withdraws its approval). |
| -Products | no | the products the app already has (a new app: PimManager, SecurityInsight) | PimManager and/or SecurityInsight: which products' permissions the app gets. |
| -Access | no | the level the app already has (a new app: Troubleshoot) | Troubleshoot (read only) or Setup (Troubleshoot + what the products' setup needs). Fewer rights than the app has = a downgrade, which needs -Force or -Confirm. |
| -SubscriptionIds | no | none | Subscriptions: Setup = Contributor + User Access Administrator; Troubleshoot = Reader + Log Analytics Reader (read only). |
| -TenantRoot | no | false | Setup: Reader at the tenant root management group, plus User Access Administrator there (SecurityInsight collecting from the whole tenant). The User Access Administrator there only when your organisation approves it (it is recorded in the Invardia portal); -Action RemoveTenantRoot keeps Reader and removes it. |
| -ResourceGroupIds | no | none | Resource group resource ids: Setup = Contributor + conditioned Role Based Access Control Administrator; Troubleshoot = Reader + Log Analytics Reader. |
| -KeyVaultIds | no | none | Key vault resource ids: Setup = Key Vault Secrets Officer; Troubleshoot = Key Vault Reader. |
| -HubVnetId | no | none | Setup: a hub VNet resource id where the app gets Network Contributor. |
| -ExchangeMailbox | no | false | Not used any more - the Invardia Support app gets no Exchange rights. Each product's mail sender is set up by your own Exchange administrator with the product's mail script: Initialize-PimMailSender (PIM Manager) or Set-SIMail (SecurityInsight). Kept only so older command lines keep working: it gives the app Exchange.ManageAsApp + the Exchange role group "Invardia Support Mail Setup" (Mail Recipient Creation + Role Management); -Action RemoveExchange takes them away again. |
| -PimMspManagingTenant | no | false | Setup for a PIM Manager MSP managing tenant: also Key Vault Crypto Officer on the key vaults named. |
| -Ring | no | 2 | Secret lifetime: 2 = 90 days (customers), 3 = 1 day (one-off setup), 1 = 2 years (Invardia's own tenants). |
| -SecretDays | no | by ring | 1-730: overrides the ring's secret lifetime. |
| -NoSecret | no | false | Do not create a new secret (keep the one you stored). |
| -ConditionalAccess | no | false | Kept for older command lines - Conditional Access is the default now. |
| -NoConditionalAccess | no | false | Do not create or update the named location and the Conditional Access policy. |
| -ConditionalAccessState | no | disabled | disabled | enabled | enabledForReportingButNotEnforced. Given explicitly, it also changes a policy that exists. |
| -SupportIp | no | 172.205.146.248 | The address the Conditional Access policy allows. |
| -DisplayName | no | Invardia Support | The app's name (the same in every customer tenant, so it is recognisable in sign-in logs). The app is found by its InvardiaSupport tag, never by this name; an existing app with another name (before 2026.10.18b: "Invardia Support for SecurityInsight - PIM Manager (customer request-based only)") is renamed to it, app registration and service principal, by the next Create or NewSecret run. |
| -ClientId | no | Unattended: sign in as your own service principal (with -CertificateThumbprint); it needs the same rights an interactive run needs. | |
| -CertificateThumbprint | no | Unattended: the certificate (with private key) in Cert:\CurrentUser\My or Cert:\LocalMachine\My - a certificate assertion, never a secret. | |
| -SignInClient | no | AzureCli | The Microsoft public client the browser sign-in uses: AzureCli, AzurePowerShell (when Conditional Access blocks the Azure CLI client) or GraphCli (Graph only - not for runs that set Azure roles). |
| -SubscriptionId | no | Kept for older automation; -Action Remove also searches this subscription. | |
| -Force | no | false | Allow a downgrade (fewer rights) without asking. |
| -PassThru | no | false | Return the app's ids (tenant, client id, object ids, level, products) as an object. |
| -WhatIf | no | false | Sign in and read, print every change it would make, change nothing. |
| -Confirm | no | false | Ask before each change (and before a downgrade). |
Preview with -WhatIf
With -WhatIf it signs in and reads the current state (with -ExchangeMailbox also Exchange: its service principals and the role group - Exchange answers reads through a POST, which changes nothing), then prints a 'What if:' line for each change it would make and makes none of them: no Graph POST/PATCH/DELETE and no Azure role assignment PUT/DELETE (only the sign-in token requests, which change nothing); no secret is created or printed; the only file it writes is its transcript in your temp folder. For an app that exists it lists every permission it would grant or revoke, every Azure role it would assign or remove, the Conditional Access changes and the new secret. For a new app it can show only 'create app registration': the grants, roles, policy and secret all need the app to exist, so they are not previewed - the table above lists them. Example: ./New-InvardiaSupportApp.ps1 -TenantId <tenant id> -Products PimManager,SecurityInsight -Access Setup -SubscriptionIds <subscription id> -WhatIf
Undo
./New-InvardiaSupportApp.ps1 -TenantId <tenant id> -Action Remove removes the app registration and its service principal, its role assignments on every subscription you can see and at the tenant root, and the Conditional Access policy and named location. Then delete the environment in the portal (portal.invardia.com > Remote support), so Invardia no longer keeps its details. To keep the app but stop access: -Action Disable. To take only the Exchange rights away: -Action RemoveExchange.
Network
It connects to: login.microsoftonline.com, graph.microsoft.com, management.azure.com, outlook.office365.com (only with -ExchangeMailbox / -Action RemoveExchange), http://localhost:<free port> on this machine (the browser sign-in answer only)
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/New-InvardiaSupportApp.ps1 -OutFile New-InvardiaSupportApp.ps1
.\New-InvardiaSupportApp.ps1 -TenantId <TenantId>To check the download first, compare its SHA-256 with the published one:
SHA-256 bf4e33d7cbc824994f3a303438631f4302d08a1430d8808f6df9f5110754566f
Checksums: SHA256SUMS.txt · Version 2026.11.09
Before you run it, compare the file's SHA-256 with its line in SHA256SUMS.txt.
Every parameter: Get-Help .\New-InvardiaSupportApp.ps1 -Full · Source: New-InvardiaSupportApp.ps1
Every script, identity and permission for your security review: PIM Manager · SecurityInsight · Entra Policy Suite