Public/NC.Connections.ps1
|
#Requires -Version 5.0 using namespace System.Management.Automation # Nebula.Core: Connections ========================================================================================================================== function Connect-EOL { <# .SYNOPSIS Establishes a connection to Exchange Online using EXO V3 module. .DESCRIPTION Imports the ExchangeOnlineManagement module (if needed) and invokes Connect-ExchangeOnline with opinionated defaults. When no explicit UserPrincipalName is supplied, the helper Find-UserConnected is used to auto-detect the interactive user. .PARAMETER UserPrincipalName UPN/e-mail used for the authentication prompt. Defaults to the current user. .PARAMETER DelegatedOrganization Optional customer tenant to target when running in delegated admin scenarios. .PARAMETER PassThru Return the Connect-ExchangeOnline result (session info) to the caller. .EXAMPLE Connect-EOL -UserPrincipalName 'admin@tenant.onmicrosoft.com' .EXAMPLE 'admin@tenant.onmicrosoft.com' | Connect-EOL -DelegatedOrganization 'customer.onmicrosoft.com' -PassThru #> [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('UPN', 'User')] [string]$UserPrincipalName, [string]$DelegatedOrganization, [switch]$PassThru ) begin { $module = Get-Module -Name ExchangeOnlineManagement -ListAvailable | Select-Object -First 1 if (-not $module) { throw "ExchangeOnlineManagement module not found. Install it with Install-Module ExchangeOnlineManagement." } if (-not (Get-Module -Name ExchangeOnlineManagement)) { Import-Module ExchangeOnlineManagement -ErrorAction Stop } $baseConnectParams = @{ ShowBanner = $false SkipLoadingCmdletHelp = $true } } process { if (-not $PSBoundParameters.ContainsKey('UserPrincipalName') -or [string]::IsNullOrWhiteSpace($UserPrincipalName)) { $UserPrincipalName = Find-UserConnected } if ([string]::IsNullOrWhiteSpace($UserPrincipalName)) { throw "Unable to determine the UserPrincipalName. Provide -UserPrincipalName explicitly." } $connectParams = $baseConnectParams.Clone() $connectParams.UserPrincipalName = $UserPrincipalName if ($PSBoundParameters.ContainsKey('DelegatedOrganization') -and $DelegatedOrganization) { $connectParams.DelegatedOrganization = $DelegatedOrganization } Write-NCMessage "Connecting to Exchange Online as $UserPrincipalName ..." -Level INFO $session = Connect-ExchangeOnline @connectParams if ($PassThru.IsPresent) { return $session } } } function Connect-Nebula { <# .SYNOPSIS Entry point to establish both Exchange Online and Microsoft Graph sessions. .DESCRIPTION Uses the private Test-* helpers to ensure Exchange Online and Microsoft Graph are connected, optionally forcing reconnects, installing modules, or skipping the Graph portion. .PARAMETER UserPrincipalName Optional explicit UPN for the Exchange Online connection. .PARAMETER GraphScopes Microsoft Graph delegated scopes to request (default User.Read.All). .PARAMETER GraphTenantId Optional tenant ID/domain for the Graph connection. .PARAMETER GraphDeviceCode Use device-code auth for Graph instead of launching a browser. .PARAMETER AutoInstall Install missing modules automatically without prompting. .PARAMETER ForceReconnect Force reconnect (skip health checks) for both services. .PARAMETER SkipGraph Only establish Exchange Online; skip Microsoft Graph. #> [CmdletBinding()] param( [string]$UserPrincipalName, [string[]]$GraphScopes = @('User.Read.All'), [string]$GraphTenantId, [switch]$GraphDeviceCode, [switch]$AutoInstall, [switch]$ForceReconnect, [switch]$SkipGraph ) Write-NCMessage "Welcome to Nebula." -Level INFO $exoConnected = Test-EOLConnection -UserPrincipalName $UserPrincipalName ` -AutoInstall:$AutoInstall.IsPresent ` -ForceReconnect:$ForceReconnect.IsPresent if (-not $exoConnected) { throw "Failed to establish Exchange Online session." } if ($SkipGraph) { return [pscustomobject]@{ ExchangeOnline = $true MicrosoftGraph = $false } } $graphConnected = Test-MgGraphConnection ` -Scopes $GraphScopes ` -TenantId $GraphTenantId ` -UseDeviceCode:$GraphDeviceCode.IsPresent ` -AutoInstall:$AutoInstall.IsPresent ` -ForceReconnect:$ForceReconnect.IsPresent ` -EnsureExchangeOnline:$false if (-not $graphConnected) { throw "Failed to establish Microsoft Graph session." } return [pscustomobject]@{ ExchangeOnline = $true MicrosoftGraph = $true } } function Disconnect-Nebula { <# .SYNOPSIS Disconnects from Exchange Online and Microsoft Graph sessions. .DESCRIPTION Calls Disconnect-ExchangeOnline (if available) and Disconnect-MgGraph, suppressing common errors and allowing targeted disconnects. .PARAMETER ExchangeOnly Disconnect only Exchange Online. .PARAMETER GraphOnly Disconnect only Microsoft Graph. #> [CmdletBinding()] param( [switch]$ExchangeOnly, [switch]$GraphOnly ) $disconnectExo = if ($GraphOnly) { $false } else { $true } $disconnectGraph = if ($ExchangeOnly) { $false } else { $true } if ($disconnectExo) { try { if (Get-Command -Name Disconnect-ExchangeOnline -ErrorAction SilentlyContinue) { Disconnect-ExchangeOnline -Confirm:$false -ErrorAction Stop Write-NCMessage "Exchange Online session disconnected." -Level INFO } } catch { Write-NCMessage "Failed to disconnect Exchange Online: $($_.Exception.Message)" -Level WARNING } } if ($disconnectGraph) { try { if (Get-Command -Name Disconnect-MgGraph -ErrorAction SilentlyContinue) { Disconnect-MgGraph -ErrorAction Stop | Out-Null Write-NCMessage "Microsoft Graph session disconnected." -Level INFO } } catch { Write-NCMessage "Failed to disconnect Microsoft Graph: $($_.Exception.Message)" -Level WARNING } } } Set-Alias -Name Leave-Nebula -Value Disconnect-Nebula |