Public/Set-VMetricContext.ps1
|
function Set-VMetricContext { <# .SYNOPSIS Switches to another tenant. .DESCRIPTION Set-VMetricContext makes another tenant you can use the current one: your organization's main tenant, a subtenant you manage as an MSSP, or one you were granted delegated access to. The switch mints a session for that tenant from your sign-in, with no new browser step, and replaces the current one. Your permissions in each tenant are the ones the console gives you there. The session you leave ends at once: the switch spends its refresh token and the server revokes it. A deployment job (New-VMetricDeployment -AsJob) running on it stops following its deployment, which goes on on the server. A switch the server refuses leaves the current session as it was. When another sign-in to that tenant is held (Connect-VMetric to it, or a sign-in a failed Connect-VMetric -Tenant kept), that session is used as it is, and nothing is spent. An API token is bound to its own tenant and cannot switch. .PARAMETER Tenant The tenant, by name or id. Get-VMetricTenant lists them; its objects can be piped in. .PARAMETER PassThru Write the new context (VirtualMetric.Context) to the pipeline. .EXAMPLE Set-VMetricContext -Tenant Contoso .EXAMPLE Get-VMetricTenant -Name 'Fabrikam*' | Set-VMetricContext -PassThru .OUTPUTS VirtualMetric.Context, with -PassThru. .LINK Get-VMetricTenant .LINK Get-VMetricContext #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')] [OutputType('VirtualMetric.Context')] param( [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)] [Alias('TenantId', 'Id')] [ValidateNotNullOrEmpty()] [string] $Tenant, [switch] $PassThru ) begin { if (-not $PSBoundParameters.ContainsKey('InformationAction')) { $InformationPreference = 'Continue' } } process { try { $current = Get-VMetricSession if (Test-VMetricSessionTenant -Session $current -Tenant $Tenant) { Write-Information "Already in tenant '$(ConvertTo-VMetricSafeText -Text ([string]$current.TenantName))'." if ($PassThru) { ConvertTo-VMetricContextObject -Session $current } return } if ($current.AuthMethod -eq 'ApiToken') { throw (New-VMetricException -Message 'An API token is bound to its own tenant. Connect with a token of that tenant, or sign in with the browser or a device code to switch.' ` -Code 'TenantSwitchUnavailable' -Category InvalidOperation) } # Another sign-in to that tenant, held already, is its own session family: switching to it spends # nothing. $held = $null foreach ($session in (Get-VMetricCachedSession)) { if ($session.ApiUrl -eq $current.ApiUrl -and $session.AuthMethod -ne 'ApiToken' -and $session.RefreshToken -and (Test-VMetricSessionTenant -Session $session -Tenant $Tenant)) { $held = $session break } } if ($held) { $tenantName = [string]$held.TenantName $tenantId = [string]$held.TenantId } else { $target = Resolve-VMetricTenant -Session $current -Tenant $Tenant $tenantName = [string](Get-VMetricMember -InputObject $target -Name 'name') $tenantId = [string](Get-VMetricMember -InputObject $target -Name 'id') } $tenantText = "tenant '$(ConvertTo-VMetricSafeText -Text $tenantName)' ($(ConvertTo-VMetricSafeText -Text $tenantId))" if (-not $PSCmdlet.ShouldProcess($tenantText, 'Switch to')) { return } if ($held) { Set-VMetricCurrentSession -Session $held $session = $held } else { # The grant spends the current session's refresh token: the new session replaces it. $session = Invoke-VMetricTenantSwitch -Session $current -TenantId $tenantId Remove-VMetricSession -Session $current Register-VMetricSession -Session $session } Write-Information "Switched to tenant '$(ConvertTo-VMetricSafeText -Text ([string]$session.TenantName))'." if ($PassThru) { ConvertTo-VMetricContextObject -Session $session } } catch { if (Test-VMetricFlowControl -ErrorRecord $_) { throw } Write-VMetricCmdletError -Cmdlet $PSCmdlet -ErrorRecord $_ } } } |