Private/TenantProfiles.ps1
|
$script:TenantProfilePath = Join-Path $HOME '.intui_tenants.json' function Get-InTUITenantProfiles { <# .SYNOPSIS Loads saved tenant profiles from disk. #> [CmdletBinding()] param() if (-not (Test-Path $script:TenantProfilePath)) { return @() } try { $content = Get-Content $script:TenantProfilePath -Raw | ConvertFrom-Json return @($content) } catch { Write-InTUILog -Level 'WARN' -Message "Failed to load tenant profiles: $($_.Exception.Message)" return @() } } function Save-InTUITenantProfile { <# .SYNOPSIS Saves the current connection as a tenant profile. #> [CmdletBinding()] param( [Parameter()] [string]$Label ) if (-not $script:Connected) { Show-InTUIWarning "Not connected. Connect first before saving a profile." return } $profiles = @(Get-InTUITenantProfiles) if (-not $Label) { $Label = Read-InTUITextInput -Message "[blue]Profile label[/]" -DefaultAnswer $script:TenantId } $existing = $profiles | Where-Object { $_.TenantId -eq $script:TenantId -and $_.Environment -eq $script:CloudEnvironment } if ($existing) { $existing.Label = $Label $existing.Account = $script:Account $existing.LastUsed = (Get-Date).ToString('yyyy-MM-dd HH:mm') } else { $profiles += [PSCustomObject]@{ Label = $Label TenantId = $script:TenantId Account = $script:Account Environment = $script:CloudEnvironment LastUsed = (Get-Date).ToString('yyyy-MM-dd HH:mm') } } try { $profiles | ConvertTo-Json -Depth 5 | Set-Content $script:TenantProfilePath -Encoding UTF8 Write-InTUILog -Message "Tenant profile saved" -Context @{ Label = $Label; TenantId = $script:TenantId } Show-InTUISuccess "Profile '$Label' saved." } catch { Show-InTUIError "Failed to save profile: $($_.Exception.Message)" Write-InTUILog -Level 'ERROR' -Message "Failed to save tenant profile: $($_.Exception.Message)" } } function Remove-InTUITenantProfile { <# .SYNOPSIS Removes a saved tenant profile. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$TenantId, [Parameter(Mandatory)] [string]$Environment ) $profiles = @(Get-InTUITenantProfiles) $profiles = @($profiles | Where-Object { -not ($_.TenantId -eq $TenantId -and $_.Environment -eq $Environment) }) try { $profiles | ConvertTo-Json -Depth 5 | Set-Content $script:TenantProfilePath -Encoding UTF8 Write-InTUILog -Message "Tenant profile removed" -Context @{ TenantId = $TenantId } } catch { Write-InTUILog -Level 'ERROR' -Message "Failed to remove tenant profile: $($_.Exception.Message)" } } function Show-InTUITenantSwitcher { <# .SYNOPSIS Shows saved tenant profiles for quick switching. #> [CmdletBinding()] param() Clear-Host Show-InTUIHeader Show-InTUIBreadcrumb -Path @('Home', 'Tenant Profiles') $profiles = @(Get-InTUITenantProfiles) if ($profiles.Count -eq 0) { Show-InTUIWarning "No saved tenant profiles. Connect to a tenant and use 'Save Current Tenant' to create one." Read-InTUIKey return } $choices = @() foreach ($tenantProfile in $profiles) { $current = if ($tenantProfile.TenantId -eq $script:TenantId -and $tenantProfile.Environment -eq $script:CloudEnvironment) { ' [green](current)[/]' } else { '' } $envLabel = if ($script:CloudEnvironments[$tenantProfile.Environment]) { $script:CloudEnvironments[$tenantProfile.Environment].Label } else { $tenantProfile.Environment } $choices += "$($tenantProfile.Label) [grey]| $envLabel | $($tenantProfile.Account) | Last: $($tenantProfile.LastUsed)[/]$current" } $choiceMap = Get-InTUIChoiceMap -Choices $choices $menuChoices = @($choiceMap.Choices + '─────────────' + 'Save Current Tenant' + 'Back') $selection = Show-InTUIMenu -Title "[blue]Tenant Profiles[/]" -Choices $menuChoices if ($selection -eq 'Back') { return } if ($selection -eq 'Save Current Tenant') { Save-InTUITenantProfile Read-InTUIKey return } $idx = $choiceMap.IndexMap[$selection] if ($null -ne $idx -and $idx -lt $profiles.Count) { $selected = $profiles[$idx] if ($selected.TenantId -eq $script:TenantId -and $selected.Environment -eq $script:CloudEnvironment) { Show-InTUIWarning "Already connected to this tenant." Read-InTUIKey return } Write-InTUILog -Message "Switching tenant via profile" -Context @{ Label = $selected.Label; TenantId = $selected.TenantId; Environment = $selected.Environment } Disconnect-MgGraph -ErrorAction SilentlyContinue $script:Connected = $false $connected = Connect-InTUI -TenantId $selected.TenantId -Environment $selected.Environment if ($connected) { $selected.LastUsed = (Get-Date).ToString('yyyy-MM-dd HH:mm') $selected.Account = $script:Account $profiles | ConvertTo-Json -Depth 5 | Set-Content $script:TenantProfilePath -Encoding UTF8 } } } function Show-InTUITenantHealthSummary { <# .SYNOPSIS Shows a quick health summary of the connected tenant on connect. #> [CmdletBinding()] param() $healthData = Show-InTUILoading -Title "[blue]Loading tenant health...[/]" -ScriptBlock { $org = Invoke-InTUIGraphRequest -Uri '/organization?$select=displayName,verifiedDomains,assignedPlans' $deviceOverview = Invoke-InTUIGraphRequest -Uri '/deviceManagement/managedDeviceOverview' -Beta $compliance = Invoke-InTUIGraphRequest -Uri '/deviceManagement/deviceCompliancePolicyDeviceStateSummary' -Beta @{ OrgName = if ($org.value) { $org.value[0].displayName } else { 'Unknown' } Domains = if ($org.value) { ($org.value[0].verifiedDomains | Where-Object { $_.isDefault }).name } else { 'Unknown' } EnrolledCount = $deviceOverview.enrolledDeviceCount ?? 0 Compliant = $compliance.compliantDeviceCount ?? 0 NonCompliant = $compliance.nonCompliantDeviceCount ?? 0 Error = $compliance.errorDeviceCount ?? 0 } } if ($null -eq $healthData) { return } $complianceRate = if ($healthData.EnrolledCount -gt 0) { [math]::Round(($healthData.Compliant / $healthData.EnrolledCount) * 100, 1) } else { 0 } $rateColor = if ($complianceRate -ge 90) { 'green' } elseif ($complianceRate -ge 70) { 'yellow' } else { 'red' } $content = @" [grey]Organization:[/] [white]$($healthData.OrgName)[/] [grey]Default Domain:[/] [white]$($healthData.Domains)[/] [grey]Enrolled Devices:[/] [white]$($healthData.EnrolledCount)[/] [grey]Compliance Rate:[/] [$rateColor]${complianceRate}%[/] [grey] Compliant:[/] [green]$($healthData.Compliant)[/] [grey] Non-compliant:[/] [red]$($healthData.NonCompliant)[/] [grey] Error:[/] [red]$($healthData.Error)[/] "@ Show-InTUIPanel -Title "[blue]Tenant Health[/]" -Content $content -BorderColor Blue } |