#Requires -Version 7.0 # PIM Manager 3.0.70 -- Set-PimSigninFrontSqlState.ps1, standalone (built by tools/setup/Build-PimSupportScripts.ps1; helpers inlined: _pimscriptdoc.ps1, ..\..\engine\_shared\pim-rest.ps1, pim-loopbackanswer.ps1, ..\..\engine\_shared\pim-sqlstore.ps1, _pimsignedin.ps1) <# .SYNOPSIS Give the sign-in front its place in a private PIM database. .DESCRIPTION Gives the PIM Manager's sign-in front exactly what it needs in the PIM database: a database user for the front's managed identity, the schema 'signin' owned by it, and the right to create tables there. It never adds a role. -WhatIf shows it first; running it again changes nothing. For a PRIVATE database (framework 12.11g item 9, front 1.3.0+), from a machine inside the network. The front keeps its sessions, token cache and key ring in two tables it creates itself in the schema 'signin'. This script gives its identity exactly that and no more: the user (made from the identity's client id), the schema owned by it, and the right to create tables. It never adds a role. Read back after each change; -WhatIf prints and changes nothing. Idempotent. Sign-in: the same as Grant-PimSupportSqlAccess.ps1 (your browser; an Azure Arc / VM machine identity is ignored). .EXAMPLE .\Set-PimSigninFrontSqlState.ps1 -TenantId -SubscriptionId -SqlServerName sql-pim-contoso -IdentityName id-pim-contoso -IdentityClientId -WhatIf Preview: connects, reads and prints the statements it would run. Then the same command without -WhatIf. .NOTES Requirements: PowerShell: 7.0 or later (pwsh). Windows PowerShell 5.1 is not supported. Role: a database owner of the PIM database -- a member of the SQL admin group (grp-pim-sql-admins) or the server's Microsoft Entra administrator. Hosts: login.microsoftonline.com, management.azure.com, *.database.windows.net (port 1433, from inside the PIM network) PERMISSIONS AND CHANGES (from Set-PimSigninFrontSqlState.ps1 manifest, PIM Manager 3.0.70; full page: https://invardia.com/docs/pim/scripts/Set-PimSigninFrontSqlState/) The person running it needs: - A database owner: a member of the SQL admin group (grp-pim-sql-admins) or the server's Microsoft Entra administrator [other, the PIM database] -- Creates the database user and the schema and grants CREATE TABLE. - browser sign-in (your own account; an Azure Arc / VM machine identity on this computer is ignored), or the Invardia Support app's session in this window [other, the target tenant and subscription] -- No Azure CLI, no PowerShell module, no certificate, no secret on the command line. What it creates, changes or grants: - create a database user for the sign-in front's managed identity, created from its client id (CREATE USER ... WITH SID, TYPE = E) when no user has that id (The PIM database) @ the one PIM database (-SqlDatabase, default PimPlatform) -- The front signs in to the database as its managed identity. Undo: DROP USER [] in the PIM database (after DROP SCHEMA signin and its tables). - create the schema 'signin', owned by that user (or its owner moved to that user) (The PIM database): owner of the schema signin only @ the schema signin -- The front keeps its sessions, token cache and key ring in two tables it creates in this schema; it can read and change nothing else. Undo: Drop the tables in schema signin, then DROP SCHEMA signin. - grant CREATE TABLE to that user (The PIM database): CREATE TABLE (database level; usable only in the schema it owns) @ the PIM database -- The front creates its two tables itself on first start. Undo: REVOKE CREATE TABLE FROM []. -WhatIf: Signs in, connects, prints the user, the schema owner and the grant as they are now, and the statements it would run. Nothing is changed. Undo: In the PIM database: drop the tables in schema signin, DROP SCHEMA signin, REVOKE CREATE TABLE and DROP USER for the front's identity. The front then cannot keep sign-ins. .LINK https://invardia.com/docs/pim/scripts/Set-PimSigninFrontSqlState/ #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)][ValidatePattern('^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')][string]$TenantId, [Parameter(Mandatory)][ValidatePattern('^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')][string]$SubscriptionId, [Parameter(Mandatory)][string]$SqlServerName, [string]$SqlDatabase = 'PimPlatform', # the front's managed identity: its name (the database user's name) and its client id (the user's SID) [Parameter(Mandatory)][ValidatePattern('^[A-Za-z0-9_.-]{1,128}$')][string]$IdentityName, [Parameter(Mandatory)][ValidatePattern('^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')][string]$IdentityClientId, # --- test seams (tests/script-docs/Set-PimSigninFrontSqlState.case.ps1); omit them for a real run --- [scriptblock]$Reach, [scriptblock]$Sql ) $ErrorActionPreference = 'Stop' # Published as ONE standalone file (https://invardia.com/support/pim/Set-PimSigninFrontSqlState.ps1): Build-PimSupportScripts.ps1 # inlines every helper loaded below by its literal path; the next line tells it to leave out the libraries' OPTIONAL loads. # BUILD-NO-OPTIONAL-LOADS # ===== BEGIN inlined helper: _PimScriptDoc.ps1 ===== <# .SYNOPSIS Framework 12.7 SCRIPT-DOC-1 + 12.10 item 11 -- the ONE place that knows where a PIM script's documentation page, download and checksum list live, the command form every surface shows (line 1 download, line 2+ run -- owner 2026-10-11), and the run frame every script a person runs uses (the first line "