<# .SYNOPSIS Is this SecurityInsight install healthy, and is it isolated? Read-only. .DESCRIPTION Reads the install's config (config/SecurityInsight.custom.ps1, without running it) and reports: 1. rows and the last time per SI table in the install's workspace (Log Analytics data plane) 2. run health per engine: the latest start and end, and how the last run ended (ExitReason) 3. the data collection rules in its resource group 4. ISOLATION -- the install's managed identity holds NO write role (Owner / Contributor / Monitoring Metrics Publisher / User Access Administrator / ...) outside its own resource group, except the grants SecurityInsight documents for it; and its data collection rule names are unique in the subscription (an engine that resolves a rule by name could otherwise send this install's data into another one) 5. the licence request (when the config names its Key Vault): none / requested / pending / approved / rejected, valid-to and the last check, from the state the updater keeps (SI-LicenceRequest-State; never the pull token). 6. updates (Pro, when the config names its Key Vault): the update source, the last manifest per kind (version, sequence, ring), the last check and any HOLD, from the state the updater keeps (SI-Update-State; never the install key). A refused manifest or an install key that could not be claimed is a finding; a hold is a note. A REJECTED request is wrong; a request's last problem is a note 6. a summary. Exit code 1 when anything is wrong, 0 otherwise. Needs no PowerShell module: Azure is reached over plain REST. Signs in as the install's own identity from its config (its managed identity, or its service principal certificate from the machine's certificate store), or as the service principal certificate named in SI_DIAGNOSTICS_APPID / SI_DIAGNOSTICS_TENANTID / SI_DIAGNOSTICS_CERTTHUMBPRINT (-SignIn). The identity needs Reader on the install's resource group and subscription, and Log Analytics Reader on the workspace. .PARAMETER ConfigPath The install's config file. Default: config/SecurityInsight.custom.ps1 of this copy. .PARAMETER SinceHours How far back to look for data and runs (default 26: one daily run plus margin). .PARAMETER RunningGraceHours A run that started longer ago than this and never ended is reported (default 4). .PARAMETER IdentityName The install's user-assigned identity, when the config does not name it and its resource group holds more than one. .PARAMETER PrincipalId The identity's object (principal) id -- any identity, also a VM's system-assigned one. .PARAMETER AllowedGrant Extra write grants that are allowed on purpose, as 'Role@/scope'. .PARAMETER SignIn Auto (default: the SI_DIAGNOSTICS_* service principal when set, otherwise Config) | Config (the install's own identity). AzContext is no longer supported: SecurityInsight v3 uses no Az PowerShell session. .EXAMPLE ./diagnostics/Test-SIInstall.ps1 .EXAMPLE ./diagnostics/Test-SIInstall.ps1 -ConfigPath ./config/SecurityInsight.custom.ps1 -SinceHours 48 -PassThru .LINK https://invardia.com/docs/si/scripts/Test-SIInstall/ .NOTES Requirements: PowerShell 7 (pwsh). Windows PowerShell 5.1 is refused at once (#Requires -Version 7.0). Role: Reader (and Log Analytics Reader on the workspace) -- on the install's resource group Hosts: *.blob.core.windows.net, *.queue.core.windows.net, *.table.core.windows.net, *.vault.azure.net, 169.254.169.254, api.loganalytics.io, graph.microsoft.com, invardia.com, login.microsoftonline.com, management.azure.com, monitor.azure.com, storage.azure.com, vault.azure.net #> [CmdletBinding(SupportsShouldProcess)] param( [string]$ConfigPath, [double]$SinceHours = 26, [double]$RunningGraceHours = 4, [string]$IdentityName, [string]$PrincipalId, [string[]]$AllowedGrant = @(), [ValidateSet('Auto', 'AzContext', 'Config')][string]$SignIn = 'Auto', [switch]$PassThru, # Tests only: replacements for the calls that leave this process (Arm, LaQuery, Graph, Now, Sleep, Print). [Parameter(DontShow)][System.Collections.IDictionary]$Seams ) #Requires -Version 7.0 # SecurityInsight 3.0.79 -- Test-SIInstall.ps1, standalone (Community edition). Built 2026-11-09T20:28:39Z from commit c1472e2f4c240c971c9559f07eef7e794b322001, source SOLUTIONS/SecurityInsight/diagnostics/Test-SIInstall.ps1, # by release/Build-SISupportScripts.ps1 (framework SUPPORT-DL-1). Download: Invoke-WebRequest https://invardia.com/support/si/Test-SIInstall.ps1 -OutFile Test-SIInstall.ps1 # It carries the 20 SecurityInsight file(s) the script loads (listed in $__siSupportFiles below, readable, each line # prefixed with "|"); at run time it writes them to a private temporary folder, checks each SHA-256, runs the original # script from there with your parameters, and removes the folder. No PowerShell modules are needed. $script:SIScriptVersion = '3.0.79' # SI #547: the version this copy reports first (stamped into its embedded setup/_shared/SI-ScriptRun.ps1 too) $__siSupportVersion = '3.0.79' $__siSupportEntry = 'diagnostics/Test-SIInstall.ps1' $__siSupportFiles = [ordered]@{} $__siSupportFiles['diagnostics/Test-SIInstall.ps1'] = @{ Sha256 = '7462f34ec43dae83fff85dcf579206f12257b712456c89f73485d6e267e2b7c5'; Text = @' |<# |.SYNOPSIS | Is this SecurityInsight install healthy, and is it isolated? Read-only. | |.DESCRIPTION | Reads the install's config (config/SecurityInsight.custom.ps1, without running it) and reports: | 1. rows and the last time per SI table in the install's workspace (Log Analytics data plane) | 2. run health per engine: the latest start and end, and how the last run ended (ExitReason) | 3. the data collection rules in its resource group | 4. ISOLATION -- the install's managed identity holds NO write role (Owner / Contributor / Monitoring Metrics | Publisher / User Access Administrator / ...) outside its own resource group, except the grants SecurityInsight | documents for it; and its data collection rule names are unique in the subscription (an engine that resolves a | rule by name could otherwise send this install's data into another one) | 5. the licence request (when the config names its Key Vault): none / requested / pending / approved / rejected, | valid-to and the last check, from the state the updater keeps (SI-LicenceRequest-State; never the pull token). | 6. updates (Pro, when the config names its Key Vault): the update source, the last manifest per kind (version, | sequence, ring), the last check and any HOLD, from the state the updater keeps (SI-Update-State; never the | install key). A refused manifest or an install key that could not be claimed is a finding; a hold is a note. | A REJECTED request is wrong; a request's last problem is a note | 6. a summary. Exit code 1 when anything is wrong, 0 otherwise. | | Needs no PowerShell module: Azure is reached over plain REST. Signs in as the install's own identity from its config | (its managed identity, or its service principal certificate from the machine's certificate store), or as the | service principal certificate named in SI_DIAGNOSTICS_APPID / SI_DIAGNOSTICS_TENANTID / SI_DIAGNOSTICS_CERTTHUMBPRINT | (-SignIn). The identity needs Reader on the install's resource group and subscription, and Log Analytics Reader on the workspace. | |.PARAMETER ConfigPath | The install's config file. Default: config/SecurityInsight.custom.ps1 of this copy. |.PARAMETER SinceHours | How far back to look for data and runs (default 26: one daily run plus margin). |.PARAMETER RunningGraceHours | A run that started longer ago than this and never ended is reported (default 4). |.PARAMETER IdentityName | The install's user-assigned identity, when the config does not name it and its resource group holds more than one. |.PARAMETER PrincipalId | The identity's object (principal) id -- any identity, also a VM's system-assigned one. |.PARAMETER AllowedGrant | Extra write grants that are allowed on purpose, as 'Role@/scope'. |.PARAMETER SignIn | Auto (default: the SI_DIAGNOSTICS_* service principal when set, otherwise Config) | Config (the install's own | identity). AzContext is no longer supported: SecurityInsight v3 uses no Az PowerShell session. | |.EXAMPLE | ./diagnostics/Test-SIInstall.ps1 |.EXAMPLE | ./diagnostics/Test-SIInstall.ps1 -ConfigPath ./config/SecurityInsight.custom.ps1 -SinceHours 48 -PassThru | |.LINK | https://invardia.com/docs/si/scripts/Test-SIInstall/ |#> |[CmdletBinding(SupportsShouldProcess)] |param( | [string]$ConfigPath, | [double]$SinceHours = 26, | [double]$RunningGraceHours = 4, | [string]$IdentityName, | [string]$PrincipalId, | [string[]]$AllowedGrant = @(), | [ValidateSet('Auto', 'AzContext', 'Config')][string]$SignIn = 'Auto', | [switch]$PassThru, | # Tests only: replacements for the calls that leave this process (Arm, LaQuery, Graph, Now, Sleep, Print). | [Parameter(DontShow)][System.Collections.IDictionary]$Seams |) | |#Requires -Version 7.0 # after the help and the param block: before the help, it hides the help from Get-Help |# framework section 12.7 / 12.10: the documentation link first, a transcript of the run, -WhatIf writes nothing |. ([IO.Path]::Combine((Split-Path -Parent $PSScriptRoot), 'setup', '_shared', 'SI-ScriptRun.ps1')) |$siRun = Start-SIScriptRun -Script 'Test-SIInstall' -Quiet:([bool]$PSBoundParameters.ContainsKey('Seams')) |try { |$ErrorActionPreference = 'Stop' |. ([IO.Path]::Combine($PSScriptRoot, '_SIInstallDiagnostics.ps1')) |if (-not $ConfigPath) { $ConfigPath = [IO.Path]::Combine((Split-Path -Parent $PSScriptRoot), 'config', 'SecurityInsight.custom.ps1') } | |$values = Read-SIInstallConfigValues -Path $ConfigPath |$target = Get-SIInstallTargetFromConfig -Values $values |if (-not $Seams) { $null = Initialize-SIDiagnosticsSignIn -SignIn $SignIn -Values $values } |$s = Merge-SIDiagnosticsSeams -Seams $Seams |$r = Invoke-SIInstallCheck -Target $target -Seams $s -SinceHours $SinceHours -RunningGraceHours $RunningGraceHours ` | -IdentityName $IdentityName -PrincipalId $PrincipalId -AllowedGrant $AllowedGrant |if ($PassThru) { $r } |exit $(if ($r.Ok) { 0 } else { 1 }) |} finally { Stop-SIScriptRun -Run $siRun } '@ } $__siSupportFiles['setup/_shared/SI-ScriptRun.ps1'] = @{ Sha256 = 'a5c4d788d516521639611af43e1b88458216ce58bdb455885cac8e2a568afbd2'; Text = @' |#Requires -Version 5.1 |<# | EVERY SCRIPT A PERSON RUNS (framework DOCS/REQUIREMENTS.md section 12.7 SCRIPT-DOC-1 + section 12.10 SECURITY-PACK-1; SI #481 / #484). | One helper, called first by each such script: | | $siRun = Start-SIScriptRun -Script '